mirror of
https://github.com/RevenueCat/purchases-ios
synced 2026-11-11 22:55:55 +05:45
* Pass presentedOfferingContext through SK2 purchase path instead of caching Instead of caching the presentedOfferingContext and retrieving it later, pass it directly as a parameter through the SK2 purchase call tree. This makes the flow deterministic and avoids potential misattribution from stale cached values. Made-with: Cursor * Always drain cached presentedOfferingContext in handlePurchasedTransaction Ensure getAndRemovePresentedOfferingContext is always called to clean up any stale cached value, even when a context is passed directly. Made-with: Cursor * Update SK2 tests to reflect that purchase path no longer clears cached context The SK2 purchase path now passes presentedOfferingContext directly via parameters instead of caching. Tests that asserted cache-clearing on cancel/failure are updated to verify that externally cached context persists, since the purchase path is no longer responsible for it. Made-with: Cursor * Pass paywallEvent through SK2 purchase path and separate tracking from caching - Separate `track(paywallEvent:)` into pure analytics (no caching side effects) - Add `cachePurchaseData`/`clearCachedPurchaseData` for explicit cache management - Thread `paywallEvent` as a parameter through SK2 purchase call tree instead of relying on the cache, avoiding the iOS 18 race condition - For SK1, cache paywallEvent alongside presentedOfferingContext - For `.myApp` flows, cache explicitly and clear on cancel/error - Add `clearCachedPurchaseData` in `.revenueCat` performPurchase on cancel/error to prevent stale SK1 cache leaking to later purchases - Make `paywallEvent` optional in `PaywallPurchasesType` purchase methods, collapsing 4-way branch to 2 - Add unit test for SK2 paywallEvent parameter-passing path Made-with: Cursor * Unify PaywallPurchasesType purchase and caching methods - Merge two purchase methods into one with optional promotionalOffer - Remove cachePresentedOfferingContext from the protocol; use cachePurchaseData(paywallEvent: nil) everywhere including PaywallExtensions Made-with: Cursor * Move SK1 cache cleanup into orchestrator instead of PurchaseHandler The orchestrator owns the SK1 cache lifecycle (it caches on purchase start), so it should also clear on cancel/error. PurchaseHandler no longer calls clearCachedPurchaseData for the .revenueCat path — that external API is now only used by the .myApp path. Made-with: Cursor * Unify presentedOfferingContext and paywallEvent into a single per-product cache Replace the two separate caches (per-product presentedOfferingContextsByProductID + global purchaseInitiatedPaywall) with a single CachedPurchaseContext struct stored in a per-product dictionary. This eliminates the asymmetry where clearing cached data was per-product for offering context but global for paywall events. Made-with: Cursor * Fix integration test build: add missing `try` for throwing property access `self.purchases` is a throwing computed property in the integration test base class, so accessing it inside a `catch` block requires explicit `try`. Made-with: Cursor * Update tests for unified cache semantics and unify MockPurchases storage - Update future-date tests: with the unified CachedPurchaseContext, only the cache insertion date matters (not the paywall event's creation date), so these tests now verify attribution occurs correctly. - Update SK2 listener date-guard test to also include a paywall event. - Unify MockPurchases' separate dictionaries into a single CachedPurchaseData struct matching the orchestrator's pattern. Made-with: Cursor * Update PurchasesOrchestratorTests protocol for renamed test method Made-with: Cursor * Fix integration test build: add missing try for throwing property access Made-with: Cursor * Fix StoreKitIntegrationTests build: add missing try for throwing property access Made-with: Cursor * Fix PurchaseHandlerTests: .revenueCat path passes paywallEvent as parameter, not via cache The test was asserting cached data existed, but with the new implementation the .revenueCat path passes paywallEvent directly through the purchase call. Updated test to verify the parameter is passed and no caching occurs. Made-with: Cursor * Rename .myApp test and add paywallEvent assertion Made-with: Cursor * Simplify doc * Update PurchaseBlock typealias to accept all purchase parameters PurchaseBlock now takes (Package, PromotionalOffer?, PaywallEvent?) instead of just (Package), ensuring mock closures correctly forward all parameters through the purchase chain. Made-with: Cursor * Split trackPurchaseInitiated into event creation and tracking Rename to createPurchaseInitiatedEvent (pure, no side effects) and inline the track call at each call site for clarity. Made-with: Cursor * Fix lint Made-with: Cursor