feat: add QPurchaseResult to QONEntitlementsUpdateListener (SUP-292)#644
feat: add QPurchaseResult to QONEntitlementsUpdateListener (SUP-292)#644NickSxti wants to merge 1 commit into
Conversation
Add an @optional method to the entitlements update listener protocol that includes QPurchaseResult, providing purchase details for deferred and background purchases (consumables, SCA, Ask to Buy). Uses respondsToSelector: dispatch for full backward compatibility — existing implementations continue to work without changes. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Self-Review: SUP-292Protocol Design (
|
NickSxti
left a comment
There was a problem hiding this comment.
Self-review (LEVER)
Logic: iOS parity with android-sdk#769. Deferred/background purchase flows (consumables, SCA, Ask-to-Buy) previously couldn't surface QONPurchaseResult alongside an entitlements update. Adds @optional method didReceiveUpdatedEntitlements:purchaseResult: to QONEntitlementsUpdateListener; 2 QNProductCenterManager call sites dispatch via respondsToSelector: so the new signature only fires when the consumer implements it.
Edge cases:
- Consumer implements only the old method: works unchanged (existing tests assert this).
- Consumer implements both: old one still fires via dispatch, but new one is preferred — confirm the dispatch logic doesn't double-invoke; the
respondsToSelector:guard selects one path per call site. - Empty entitlements + non-nil
purchaseResult: primary reason this was added — covered by unit test. - Nil
purchaseResult: listener should still be invoked with whatever entitlements exist.
Verification:
- Unit tests for protocol conformance (backward compat) and new listener invocation with
purchaseResult. - Framework builds (
Qonversion-iOSscheme). - Sample app updated to demonstrate new method.
- Full CI run + sample-app smoke test pending (tickboxes in PR still open).
Effects / blast radius:
- Public API surface grows by one
@optionalmethod — non-breaking. - 2 call sites in
QNProductCenterManagergain dispatch logic. - ABI stable; consumers without the new method continue to link against existing API.
Risks / rollback:
- Revert removes the new method; sample app revert would restore prior example; no consumer would break.
- If
QONPurchaseResultstruct ever changes shape, this listener signature has to stay in lockstep with the Android equivalent. - Ensure Android (#769) and iOS (#644) ship together to keep cross-SDK parity.
|
Superseded by #648 (QONDeferredPurchasesListener, shipped in iOS SDK 6.10.0 on 2026-04-06). The overload approach was replaced with a dedicated protocol; QONEntitlementsUpdateListener method is now marked |
Summary
@optionalmethoddidReceiveUpdatedEntitlements:purchaseResult:toQONEntitlementsUpdateListenerprotocolQNProductCenterManagerto dispatch viarespondsToSelector:— new method getsQONPurchaseResult, old method works unchangedContext
iOS parity with Android SDK PR #769. For deferred/background purchases (consumables, SCA, Ask to Buy), the listener now receives the
QONPurchaseResultalongside entitlements, allowing developers to access purchase details even when entitlements are empty.Non-breaking: Uses
@optionalprotocol method — existing implementations continue to work without code changes.Linear: SUP-292
Related: Android PR #769
Test plan
Qonversion-iOSscheme)🤖 Generated with Claude Code