purchases-ios icon indicating copy to clipboard operation
purchases-ios copied to clipboard

Seamless SK2 Observer Mode

Open fire-at-will opened this issue 9 months ago • 1 comments

Motivation

The current 5.0 betas require developers using observer mode with StoreKit 2 to call Purchases.shared.handleObserverModeTransaction(result) after processing a purchase. While this works, it’s an additional step for developers and, if a developer doesn’t include it, will likely lead to purchases being missed. We’ve been looking for a way around this, and until now haven’t been able to come up with one until recently.

This POC demonstrates a method that might allow us to achieve "seamless" observer mode with StoreKit 2 without calling Purchases.shared.handleObserverModeTransaction(result).

Approach

In this approach, the SDK detects when the app is foregrounded after being backgrounded by the purchase modals. When it is foregrounded, it performs the following to observe the purchase:

  1. Check the on-device cache to obtain a list of transaction IDs that have been previously observed by this method.
  2. Get a list of all transactions for the user by querying StoreKit 2’s Transaction.all API.
  3. Observe the latest transaction by sending it to Khepri. If there are multiple unsynced transactions, Khepri will find them when it fetches the list of most recent transactions from the list transactions API.

Technical Details

Notable New Classes

  • StoreKit2ObserverModeManager: A class owned by PurchasesOrchestrator that determines when observer mode should check for new transactions. If any new transactions are found, it forwards the most recent transaction to the PurchasesOrchestrator via its conformance to the StoreKit2ObserverModeManagerDelegate protocol to be processed.
  • StoreKit2ObserverModePurchaseDetector: An actor that checks for unsynced transactions, and if any are found, sends them the provided StoreKit2ObserverModeManagerDelegate for processing. It's an actor to prevent any potential race condition schenanigans with how it caches the list of synced transaction IDs. Owned by the StoreKit2ObserverModeManager.

TODO

  • Remove the requirement that non-builder based configure functions force the developer to specify a StoreKitVersion, and instead just default to StoreKit2. This was intentionally excluded from this PR since it's already pretty large in size.

fire-at-will avatar Apr 26 '24 15:04 fire-at-will

1 Warning
:warning: This PR increases the size of the repo by more than 100.00 KB (increased by 100.81 KB).

Generated by :no_entry_sign: Danger

RevenueCat-Danger-Bot avatar Apr 26 '24 15:04 RevenueCat-Danger-Bot