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

苹果开发者后台配置的内购产品在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配置文件:
    1. Xcode新建文件,选择StoreKit Configuration File,手动添加和App Store Connect一致的内购产品
    2. 打开项目Scheme,选择Run-Options,将StoreKit Configuration设置为你刚创建的配置文件
  • 建议使用iOS 15及以上版本的模拟器测试,更低版本的模拟器对StoreKit支持不完善,优先使用真机测试更稳定

3. 调试技巧

运行项目后查看Xcode控制台输出:

  • 如果打印Invalid identifiers found: xxx,说明产品ID不匹配或者内购产品配置错误
  • 如果打印Request did fail: xxx,根据具体错误信息排查网络或者权限问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 18:15:02