StoreKit 1 vs StoreKit 2
Choose StoreKit 1 or StoreKit 2 in the Superwall iOS SDK. See the default, when the SDK uses StoreKit 1 anyway, and which features need StoreKit 2.
The Superwall iOS SDK uses Apple's StoreKit to load products, make purchases and read the user's purchase history. It can use StoreKit 2 or the older StoreKit 1. StoreKit 2 is the default, and most apps should keep it.
This page is for iOS apps that need to know which version runs: apps that set the version themselves, use observer mode, configure the SDK from Objective-C, or sell consumables.
Requirements
- iOS SDK 4.0.0 or later. The
storeKitVersionoption arrived in 4.0.0, which also made StoreKit 2 the default. - iOS 15 or later for StoreKit 2. Since iOS SDK 4.18.0, the SDK itself needs iOS 15, so StoreKit 2 works on every device it runs on. From 4.0.0 up to 4.18.0, devices on iOS 13 and 14 use StoreKit 1.
Choose the version
Set storeKitVersion on SuperwallOptions when you configure the SDK. It takes .storeKit2 (the default) or .storeKit1:
let options = SuperwallOptions()
options.storeKitVersion = .storeKit1
Superwall.configure(apiKey: "MY_API_KEY", options: options)Leave it out to use StoreKit 2.
When the SDK uses StoreKit 1
In these cases the SDK uses StoreKit 1, or you have to:
- Objective-C with a purchase controller. If you configure the SDK from Objective-C and pass a
PurchaseController, the SDK uses StoreKit 1, even if you set.storeKit2. - Objective-C with observer mode. If you configure the SDK from Objective-C and set
shouldObservePurchasestotrue, the SDK uses StoreKit 1, even if you set.storeKit2. - Objective-C with
purchase(_:). If you callpurchase(_:)from Objective-C, setstoreKitVersionto.storeKit1yourself. - Consumables on iOS 17 and earlier. If your
Info.plistsetsSKIncludeConsumableInAppPurchaseHistorytotrue, the default is StoreKit 2 on iOS 18 and later, and StoreKit 1 on earlier versions. If you setstoreKitVersionyourself, the SDK uses your value instead. See Consumable Products.
The first two apply only to the Objective-C configure method. Configuring from Swift with a purchase controller or observer mode keeps the version you set.
Features that need StoreKit 2
- Introductory offer eligibility override. The SDK applies the eligibility token only to StoreKit 2 purchases. A purchase controller has to buy
product.sk2Productand pass the token itself. - Monthly billing plans. The SDK applies the billing plan to StoreKit 2 purchases on iOS 26.4 and later. On StoreKit 1,
isBillingPlanAvailableis alwaysfalse. - Refunds. Without a purchase controller, a refunded purchase stops giving the user an active entitlement (iOS SDK 4.0.3 and later).
- Consumables. A consumable doesn't count as a lifetime purchase.
- Billing grace period. An App Store subscription in a billing grace period stays active until the grace period ends (iOS SDK 4.18.3 and later).
Observer mode
Observer mode (shouldObservePurchases) works with both versions, with some differences:
| StoreKit 2 | StoreKit 1 | |
|---|---|---|
| iOS version | iOS 17.2 or later | Any iOS version the SDK supports |
| Events Superwall reports | Transaction completions | Transaction starts, abandons and completions |
On StoreKit 2, the SDK checks for new transactions each time the app becomes active. Superwall doesn't finish transactions in observer mode, so your app has to finish them.
Purchase controllers
If you use a purchase controller, the StoreProduct passed to purchase(product:) holds the product for the version in use:
product.sk2Producton StoreKit 2.product.sk1Producton StoreKit 1.sk2Productisnil.
Check for both if your app can run either version, for example because of the Objective-C or consumable cases above.
Things to know
- On StoreKit 1, restoring purchases refreshes the App Store receipt, which can ask the user to sign in to their Apple Account.
- In Expo, set the same option with
storeKitVersion: "STOREKIT1"or"STOREKIT2"in theSuperwallProvideroptions. - The SDK sets up its product loading and purchasing for one version when you call
configure. SetstoreKitVersionbefore that call.
Related
How is this guide?
Overriding Introductory Offer Eligibility
Control when users see free trials and intro offers on your paywalls by overriding the default eligibility logic.
Retrieving and Presenting a Paywall Yourself
Get a paywall yourself with getPaywall on iOS and present the PaywallViewController or SwiftUI PaywallView however you like, with skip and error handling.