iOS 18适配:SKPaymentQueue弃用后如何实现App Store内购?
iOS 18 适配 App Store 内购(替代弃用的 SKPaymentQueue/SKPaymentTransaction)
iOS 18 彻底弃用了旧版 StoreKit 1 的 SKPaymentQueue、SKPaymentTransaction 等 API,需要切换到 StoreKit 2 的异步化 API 实现内购功能,以下是具体适配步骤:
核心修改方向
去掉旧的队列监听逻辑,改用 StoreKit 2 提供的 Product.purchase()、Transaction 相关 API 处理购买、交易更新和权限同步,完全替代原有流程。
1. 删除旧的队列监听代码
直接删掉以下内容:
- 实现
SKPaymentTransactionObserver的扩展 - 初始化方法里的
SKPaymentQueue.default().add(self)调用 - 基于旧队列的
observeTransactionUpdates()相关逻辑
2. 实现新的购买流程
新增购买产品的异步方法,用 Product.purchase() 替代旧的队列提交,直接处理返回的 PurchaseResult:
func purchaseProduct(_ product: Product) async throws { let purchaseResult = try await product.purchase() switch purchaseResult { case .success(let verificationResult): // 处理交易验证结果(建议优先服务器验证,本地验证仅作兜底) switch verificationResult { case .verified(let transaction): // 验证通过,同步用户权限 entitlementManager.updateEntitlements(with: transaction) // 标记交易完成 await transaction.finish() case .unverified(_, let error): print("交易验证失败: \(error.localizedDescription)") } case .userCancelled: print("用户取消购买") case .pending: print("购买待处理(如需要家长审核)") @unknown default: print("未知购买结果") } }
3. 监听交易状态更新
用 Transaction.updates 异步流替代旧的 updatedTransactions 方法,监听订阅续订、待处理交易完成等场景:
init(entitlementManager: EntitlementManager) { self.entitlementManager = entitlementManager super.init() // 启动交易更新监听 Task { for await update in Transaction.updates { switch update { case .verified(let transaction): entitlementManager.updateEntitlements(with: transaction) await transaction.finish() case .unverified(_, let error): print("交易更新验证失败: \(error.localizedDescription)") } } } }
4. 实现恢复购买功能
用 Transaction.restore() 替代旧的 restoreCompletedTransactions 方法,恢复用户已购项目:
func restorePurchases() async throws { let restoredTransactions = try await Transaction.restore() for transaction in restoredTransactions { switch transaction { case .verified(let verifiedTransaction): entitlementManager.updateEntitlements(with: verifiedTransaction) await verifiedTransaction.finish() case .unverified(_, let error): print("恢复交易验证失败: \(error.localizedDescription)") } } }
5. 处理应用内跳转购买
旧的 shouldAddStorePayment 代理方法不再需要,StoreKit 2 会自动处理从 App Store 跳转至应用内的购买请求,直接通过上述购买流程处理即可。
注意事项
- 确保你的
EntitlementManager能接收Transaction对象,从中解析产品 ID、订阅周期、过期时间等信息来更新用户权限 - 交易验证建议通过后端服务器完成,避免本地验证被篡改
- 若项目最低部署版本低于 iOS 15,需用
if #available(iOS 15.0, *)包裹 StoreKit 2 代码,保留旧 API 作为兼容兜底;如果仅适配 iOS 18+,可直接将最低版本升至 iOS 15+
内容的提问来源于stack exchange,提问作者macybooky
相关产品推荐
相关产品推荐

