purchases-ios
purchases-ios copied to clipboard
Seamless SK2 Observer Mode
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:
- Check the on-device cache to obtain a list of transaction IDs that have been previously observed by this method.
- Get a list of all transactions for the user by querying StoreKit 2’s Transaction.all API.
- 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 byPurchasesOrchestrator
that determines when observer mode should check for new transactions. If any new transactions are found, it forwards the most recent transaction to thePurchasesOrchestrator
via its conformance to theStoreKit2ObserverModeManagerDelegate
protocol to be processed. -
StoreKit2ObserverModePurchaseDetector
: An actor that checks for unsynced transactions, and if any are found, sends them the providedStoreKit2ObserverModeManagerDelegate
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 theStoreKit2ObserverModeManager
.
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.
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