迁移至StoreKit 2后读取sandboxReceipt文件报错求助
问题描述
我正在使用WWDC 2021介绍的StoreKit 2处理交易,迁移后尝试验证收据并遍历交易时,出现错误:The file “sandboxReceipt” couldn’t be opened because there is no such file。
以下是用于获取收据的代码:
// Access the app's bundle let bundle = Bundle.main // Get the appStoreReceiptURL property, which points to the receipt file location guard let receiptURL = bundle.appStoreReceiptURL else { print("No receipt URL found.") return nil } do { // Read the data from the receipt file let receiptData = try Data(contentsOf: receiptURL) // Convert the receipt data to a base64-encoded string let base64Receipt = receiptData.base64EncodedString() // Return the base64-encoded receipt string return base64Receipt } catch { print("Error reading receipt data: \(error.localizedDescription)") return nil }
解决方案
核心原因:StoreKit 2不再依赖本地收据文件进行交易验证与查询,它提供了更直接、安全的API来获取交易信息,手动读取appStoreReceiptURL的逻辑已不符合新框架的设计思路。
1. 优先使用StoreKit 2原生交易API
直接通过Transaction类获取用户交易记录,无需处理本地收据文件:
import StoreKit // 获取当前有效的所有权益交易 Task { do { let transactions = try await Transaction.currentEntitlements for transaction in transactions { // 处理交易信息 if let productID = transaction.productID { print("已购产品ID:\(productID)") } // 可选:自定义验证交易签名 switch transaction.verified { case .unverified(_, let error): print("交易验证失败:\(error.localizedDescription)") case .verified(let verifiedTx): print("验证通过的交易:\(verifiedTx.transactionID)") } } } catch { print("获取交易列表失败:\(error.localizedDescription)") } }
2. 若需兼容旧收据逻辑(不推荐)
如果必须保留收据读取流程,需先触发App Store刷新收据文件:
import StoreKit func refreshAndFetchReceipt() { Task { do { // 同步交易并刷新收据 try await AppStore.sync() guard let receiptURL = Bundle.main.appStoreReceiptURL, FileManager.default.fileExists(atPath: receiptURL.path) else { print("刷新后仍无收据文件") return } let receiptData = try Data(contentsOf: receiptURL) let base64Receipt = receiptData.base64EncodedString() // 使用base64格式的收据进行后续操作 } catch { print("刷新或读取收据失败:\(error.localizedDescription)") } } }
注意:此方案仅作为临时兼容手段,StoreKit 2的设计目标就是替代传统的收据验证流程,建议逐步迁移到原生API。
3. 沙盒环境额外注意事项
- 确保测试设备已登录沙盒测试账号(不要使用正式Apple ID)
- 首次安装应用后无收据文件属于正常情况,需完成至少一次内购交易(包括免费订阅),或调用
AppStore.sync()触发收据生成
内容的提问来源于stack exchange,提问作者ARR
相关产品推荐
相关产品推荐

