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
.storekit
file → 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 Configuration
to 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
.storekit
only 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