苹果开发者后台配置的内购产品在App中无法正常显示问题求助
问题根因及修复方案
1. 代码问题修复
你当前的StoreManager存在两个核心错误:
- 未声明遵守
SKPaymentTransactionObserver协议,也没有将自身注册为支付队列的观察者,交易相关回调无法正常触发 getProducts方法中创建的SKProductsRequest是局部变量,方法执行结束后就会被释放,会导致产品请求的代理回调无法接收
修正后的StoreManager代码如下:
class StoreManager: NSObject, ObservableObject, SKProductsRequestDelegate, SKPaymentTransactionObserver { @Published var myProducts = [SKProduct]() var request: SKProductsRequest! @Published var transactionState: SKPaymentTransactionState? override init() { super.init() // 注册为支付队列观察者 SKPaymentQueue.default().add(self) } deinit { // 移除观察者避免内存泄漏 SKPaymentQueue.default().remove(self) } func purchaseProduct(product: SKProduct) { if SKPaymentQueue.canMakePayments() { let payment = SKPayment(product: product) SKPaymentQueue.default().add(payment) } else { print("User can't make payment.") } } func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) { for transaction in transactions { switch transaction.transactionState { case .purchasing: transactionState = .purchasing case .purchased: UserDefaults.standard.setValue(true, forKey: transaction.payment.productIdentifier) queue.finishTransaction(transaction) print("payment success") transactionState = .purchased case .restored: UserDefaults.standard.setValue(true, forKey: transaction.payment.productIdentifier) queue.finishTransaction(transaction) transactionState = .restored case .failed, .deferred: queue.finishTransaction(transaction) transactionState = .failed print("payment failed") default: queue.finishTransaction(transaction) } } } func getProducts(productIDs: [String]) { print("Start requesting products ...") // 赋值给类属性避免被提前释放 request = SKProductsRequest(productIdentifiers: Set(productIDs)) request.delegate = self request.start() } func productsRequest(_ request: SKProductsRequest, didReceive response: SKProductsResponse) { print("Did receive response") if !response.products.isEmpty { DispatchQueue.main.async { self.myProducts = response.products } } for invalidIdentifier in response.invalidProductIdentifiers { print("Invalid identifiers found: \(invalidIdentifier)") } } func request(_ request: SKRequest, didFailWithError error: Error) { print("Request did fail: \(error)") } }
2. 项目配置检查
完成代码修改后,依次检查以下配置项,遗漏任意一项都会导致内购产品无法加载:
- 打开Xcode项目的
Signing & Capabilities标签页,确认已经添加In-App Purchase能力 - 确认App Store Connect中创建的内购产品ID和代码中
productIDs数组里的字符串完全一致(大小写敏感),且产品状态为「准备提交」及以上,不能是草稿状态 - 若使用模拟器测试,需要添加本地StoreKit配置文件:
- Xcode新建文件,选择
StoreKit Configuration File,手动添加和App Store Connect一致的内购产品 - 打开项目Scheme,选择
Run-Options,将StoreKit Configuration设置为你刚创建的配置文件
- Xcode新建文件,选择
- 建议使用iOS 15及以上版本的模拟器测试,更低版本的模拟器对StoreKit支持不完善,优先使用真机测试更稳定
3. 调试技巧
运行项目后查看Xcode控制台输出:
- 如果打印
Invalid identifiers found: xxx,说明产品ID不匹配或者内购产品配置错误 - 如果打印
Request did fail: xxx,根据具体错误信息排查网络或者权限问题
内容的提问来源于stack exchange,提问作者George Sepetadelis
相关产品推荐
相关产品推荐

