You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 20:44:56