Swift基于RevenueCat实现推广内购:defermentBlock缓存及调用问题
推广内购接入问题解决方案
1. 现有代码的核心问题
你当前代码的核心问题是在defermentBlock的回调中重复调用了purchaseProduct方法:defermentBlock本身就会触发完整的购买流程,二次调用会直接导致逻辑冲突,这是功能异常的首要原因,回调内只需要处理购买结果即可,不需要再次发起购买请求。
2. defermentBlock缓存方案
直接在AppDelegate中声明两个可选属性用于缓存即可,示例如下:
// AppDelegate类内新增属性 var deferredPurchaseBlock: RCDeferredPromotionalPurchaseBlock? var deferredPromoProduct: SKProduct?
代理方法改为仅做缓存逻辑,不要直接调用block:
func purchases(_ purchases: Purchases, shouldPurchasePromoProduct product: SKProduct, defermentBlock makeDeferredPurchase: @escaping RCDeferredPromotionalPurchaseBlock) { // 缓存前先清空旧数据避免内存问题 self.deferredPurchaseBlock = nil self.deferredPromoProduct = nil // 存储当前推广购买的block和对应产品 self.deferredPurchaseBlock = makeDeferredPurchase self.deferredPromoProduct = product }
3. 合适的调用时机
需要同时满足以下所有条件再调用缓存的block,避免打断用户正常操作:
- 应用已经进入前台活跃状态,启动流程完全结束
- 用户已经完成登录/身份校验流程,RevenueCat的用户ID已设置完成,避免购买归属到错误账号
- 应用当前没有正在进行的其他购买流程、没有全屏弹窗遮挡主界面、用户没有处于敏感操作流程(例如账号注销、内容提交等)
- 通常可以放在应用主界面的
onAppear回调中,或者监听应用活跃状态通知触发校验
调用逻辑示例:
// 时机合适时取出缓存的block执行 guard let appDelegate = UIApplication.shared.delegate as? AppDelegate, let deferBlock = appDelegate.deferredPurchaseBlock, let _ = appDelegate.deferredPromoProduct else { return } deferBlock { transaction, purchaserInfo, error, cancelled in // 直接处理购买结果即可 if error == nil, !cancelled, let _ = purchaserInfo { try? CoreDataManagerNew.shared.updateUserInformation() } // 执行完成后清空缓存,避免重复触发 appDelegate.deferredPurchaseBlock = nil appDelegate.deferredPromoProduct = nil }
4. 测试无效果的排查方案
按优先级依次排查:
- 卸载设备上所有同包名的正式版/TestFlight版应用,完全杀掉后台进程后再安装开发测试包
- 测试使用的Apple ID必须是沙盒测试账号,不能使用正式Apple ID
- 确认App Store Connect中对应推广内购产品的元数据已经填写完整,状态为已批准
- 确认RevenueCat SDK版本高于3.0.0,低于该版本的SDK对推广内购的支持存在缺陷
- 测试时必须先完全关闭应用进程,再触发测试跳转,应用处于后台运行状态时不会触发代理回调
内容的提问来源于stack exchange,提问作者Lukas
相关产品推荐
相关产品推荐

