StoreKit订阅过期观测及Transaction.currentEntitlements调用相关问题
StoreKit 在 ObservableObject 中的适配疑问解答
我在适配StoreKit到ObservableObject模型时存在一些困惑。按照我的理解,如果应用启动时订阅处于激活状态,但后续订阅失效,唯一的检测方式是调用Transaction.currentEntitlements并检查订阅的currentEntitlements是否为.verified。
以下是我的两个疑问及对应的解答:
疑问一:检查当前订阅状态时是否需要调用finish()?
我写了这样的检查方法,不确定是否要在verified分支里调用finish():
private func isPurchased(product: Product) async -> Bool { guard let state = await product.currentEntitlement else { return false } switch state { case .unverified(_, _): return false case .verified(let verifiedProduct): // Necessary?? await verifiedProduct.finish() return true } }
解答:不需要在这里调用finish()。Transaction.finish()的核心作用是通知StoreKit:你已经完成了该交易的业务处理(比如给用户解锁功能、记录购买记录),避免StoreKit重复推送该交易事件。而currentEntitlements返回的是当前有效的订阅权益凭证,这类凭证不需要被"结束"——它们只是用来确认用户当前是否拥有权限的依据。
只有在处理Transaction.updates流中的交易事件(比如新购买成功、订阅自动续期、用户申请退款等)时,才需要在完成对应业务逻辑后调用finish()。
疑问二:何时调用Transaction.currentEntitlements?有没有可观测的状态变化机制?
我需要在订阅过期时立即更新UI,但不确定StoreKit是否提供了可观测的机制,难道必须用定时器频繁检查Transaction.currentEntitlements?
解答:不需要定时器轮询,StoreKit提供了原生的状态更新监听机制:
- 监听
Transaction.updates异步流:这个流会在订阅状态发生变更时(包括订阅过期、续期、退款、权限恢复等)自动推送交易事件。你可以在ObservableObject的初始化方法中启动监听,一旦收到事件就更新本地的订阅状态变量,触发UI刷新。 - 应用启动时调用一次:用来初始化当前的订阅状态,确保应用启动时UI能正确显示用户的权限情况。
- 应用从后台回到前台时调用一次:补充兜底,避免订阅在后台过期后,前台UI没能及时同步状态。
定时器轮询不仅会增加不必要的网络开销,还可能导致UI更新延迟,优先使用Transaction.updates流是更高效可靠的方案。
内容的提问来源于stack exchange,提问作者CalebK
相关产品推荐
相关产品推荐

