Xcode StoreKit Configuration: Complete Guide to Local In-App Purchase and Subscription Testing
Contents
Xcode StoreKit Configuration: Complete Guide to Local In-App Purchase and Subscription Testing
During app development, using a StoreKit configuration file (.storekit) allows local simulation of payment flows without network or sandbox accounts. This article details setup, testing, and related code to help you efficiently develop and debug IAP.
Why StoreKit Configuration?
A StoreKit configuration file acts like a “virtual store” to simulate various purchase and subscription scenarios locally, speeding iteration and avoiding frequent sandbox account switching or App Store review waiting.
Setup Steps
1. Create a StoreKit Configuration File
- In Xcode Project Navigator, right-click the project folder →
New File... - Search “StoreKit” → select “StoreKit Configuration File” →
Next - Name it (e.g.,
Test.storekit) →Create
2. Add Products in .storekit
- Open the
.storekitfile → click “+” → choose type (consumable, non-consumable, subscription, etc.) - Configure product IDs, prices, subscription periods
3. Associate .storekit to Scheme
- Menu:
Product>Scheme>Edit Scheme... - Left:
Run>Options - Right: set
StoreKit Configurationto your.storekit - Save
4. Run and Test
- Run the app; Xcode will use the StoreKit configuration to simulate purchases
- Works on simulator and devices, no network or sandbox login needed
Swift Example (StoreKit 2)
import StoreKit
@MainActor
class StoreKitManager: ObservableObject {
@Published var products: [Product] = []
// Load products
func fetchProducts() async {
do {
let storeProducts = try await Product.products(for: ["com.example.test.coin100", "com.example.test.vip"])
self.products = storeProducts
} catch {
print("Failed to fetch products: \(error)")
}
}
// Purchase
func purchase(product: Product) async {
do {
let result = try await product.purchase()
switch result {
case .success(let verification):
switch verification {
case .verified(let transaction):
print("Purchase success: \(transaction.productID)")
await transaction.finish()
case .unverified(_, let error):
print("Unverified purchase: \(error)")
}
case .userCancelled:
print("User cancelled")
case .pending:
print("Pending")
@unknown default:
break
}
} catch {
print("Purchase error: \(error)")
}
}
}Common Test Scenarios
- Consumable and non-consumable purchases
- Subscriptions and renewals
- Restore purchases
- Failures, cancellations, refunds
- Upgrade/downgrade/crossgrade
Notes
.storekitonly affects local testing; not sandbox or production- Modify product parameters anytime; changes take effect immediately
- Configure complex scenarios (time acceleration, subscription upgrades) directly in
.storekit
References
- Apple: Testing at all stages of development with Xcode and the sandbox
- Apple: StoreKit testing in Xcode
WenHaoFree