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

如何在StoreKit 2中监听恢复购买响应以触发文件下载?

在iOS 17 + StoreKit 2中监听内购恢复完成并触发文件下载

要监听内购恢复完成事件并触发文件下载,你需要结合AppStore.sync()的异步完成回调,以及监听Transaction.updates交易更新流——这是StoreKit 2中处理交易状态变化的核心方式。

1. 监听交易更新流

在你的视图中添加onReceive来监听Transaction.updates,所有恢复的交易都会通过这个流推送,你可以在这里处理下载逻辑:

struct YourView: View {
    @State private var isRestoring = false
    
    var body: some View {
        // 你的视图内容
        .toolbar {
            ToolbarItem {
                Button("Restore") {
                    isRestoring = true
                    Task.detached {
                        defer { isRestoring = false }
                        do {
                            try await AppStore.sync()
                            // sync完成后可主动检查已购项目(可选兜底逻辑)
                            await checkRestoredPurchases()
                        } catch {
                            // 处理恢复失败场景,比如用户取消登录
                            print("恢复失败:\(error.localizedDescription)")
                        }
                    }
                }
                .disabled(isRestoring)
            }
        }
        .onReceive(Transaction.updates) { transactions in
            Task {
                for await transaction in transactions {
                    await handleRestoredTransaction(transaction)
                }
            }
        }
    }
    
    private func handleRestoredTransaction(_ transaction: Transaction) async {
        // 过滤无效交易(已撤销、无产品ID等)
        guard transaction.isRevoked == false,
              let productID = transaction.productID else {
            await transaction.finish()
            return
        }
        
        // 匹配目标内购项目,触发下载
        if productID == "你的目标内购项目ID" {
            startFileDownload(for: productID)
        }
        
        // 必须调用finish()结束交易生命周期,否则会重复触发更新
        await transaction.finish()
    }
    
    private func checkRestoredPurchases() async {
        // 主动查询用户当前所有有效已购项目,兜底处理流推送遗漏的情况
        for await entitlement in Transaction.currentEntitlements {
            guard let productID = entitlement.productID else { continue }
            if productID == "你的目标内购项目ID" {
                startFileDownload(for: productID)
            }
        }
    }
    
    private func startFileDownload(for productID: String) {
        // 这里实现你的文件下载逻辑
        print("开始下载对应项目的文件:\(productID)")
    }
}

关键说明

  • Transaction.updates会推送所有交易状态变化,包括恢复操作带来的交易更新,是最可靠的监听入口。
  • 处理完交易后必须调用await transaction.finish(),否则交易状态会一直处于未完成状态,导致重复触发更新。
  • AppStore.sync()执行完成后调用checkRestoredPurchases()是兜底逻辑,避免因流推送延迟导致的恢复事件遗漏。
  • Xcode测试环境中的弹窗是模拟Apple ID登录流程,点击OK后恢复流程会自动完成,此时交易更新流会收到对应的恢复交易。

内容的提问来源于stack exchange,提问作者neowinston

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 22:27:14