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 storeKitVersion option 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:

  1. 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.
  2. Objective-C with observer mode. If you configure the SDK from Objective-C and set shouldObservePurchases to true, the SDK uses StoreKit 1, even if you set .storeKit2.
  3. Objective-C with purchase(_:). If you call purchase(_:) from Objective-C, set storeKitVersion to .storeKit1 yourself.
  4. Consumables on iOS 17 and earlier. If your Info.plist sets SKIncludeConsumableInAppPurchaseHistory to true, the default is StoreKit 2 on iOS 18 and later, and StoreKit 1 on earlier versions. If you set storeKitVersion yourself, 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.sk2Product and 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, isBillingPlanAvailable is always false.
  • 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 2StoreKit 1
iOS versioniOS 17.2 or laterAny iOS version the SDK supports
Events Superwall reportsTransaction completionsTransaction 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.sk2Product on StoreKit 2.
  • product.sk1Product on StoreKit 1. sk2Product is nil.

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 the SuperwallProvider options.
  • The SDK sets up its product loading and purchasing for one version when you call configure. Set storeKitVersion before that call.

How is this guide?

On this page