WatchOS 8下StoreKit 2的subscription status返回空数组如何解决
StoreKit 2 独立WatchOS 8订阅状态返回空问题解答
问题诱因
该问题是Xcode 13 + WatchOS 8环境下的已知兼容性问题,核心原因有两点:
- 独立WatchOS应用在Xcode 13的模拟Store测试环境中,不会自动同步iOS端的交易凭证,也不会持久化本地生成的交易记录到系统级StoreKit缓存,二次启动应用后缓存丢失,导致
subscription.status无法读取到有效交易 - WatchOS 8的StoreKit 2原生实现存在缺陷,
Product.Subscription.status接口默认优先读取已同步到iCloud的交易凭证,独立Watch应用如果未开启iCloud能力,或测试环境下iCloud同步未激活,就会返回空数组,该缺陷已在WatchOS 9及以上版本修复。
可行解决方案
临时测试适配方案
- 替换
subscription.status调用逻辑,优先通过Transaction.currentEntitlements遍历所有生效交易凭证,手动匹配订阅商品ID判断订阅有效性,参考代码如下:
await requestProducts() guard let product = subscriptions.first else { print("No Subscriptions"); return } guard let sub = product.subscription else { print("Not Subscription",product.id); return } // 替代原有sub.status调用逻辑 var isSubscriptionActive = false for await result in Transaction.currentEntitlements { guard case .verified(let transaction) = result else { continue } if transaction.productID == product.id { isSubscriptionActive = transaction.expirationDate ?? .distantPast > Date() break } }
- 测试阶段可在完成购买后,将交易ID、有效期等核心信息存储到本地Keychain,二次启动后优先读取本地存储的订阅状态,避免依赖StoreKit的不稳定缓存。
正式上线兼容方案
- 升级开发工具到Xcode 14及以上版本,将WatchOS部署目标升级到9.0及以上,该版本已原生修复独立Watch应用StoreKit 2的状态读取缺陷
- 若需保留对WatchOS 8的兼容,完全弃用
subscription.status接口,统一使用Transaction.currentEntitlements做订阅有效性校验,该接口在WatchOS 8下的兼容性表现更稳定 - 为独立Watch应用开启iCloud能力,勾选iCloud配置中的「Key-value storage」和「CloudKit」选项,保证交易凭证可以正常同步到系统级存储。
内容的提问来源于stack exchange,提问作者EPage_Ed
相关产品推荐
相关产品推荐

