使用RevenueCat订阅时,点击订阅确认OK后无回调如何处理?
问题
使用RevenueCat实现订阅功能时,测试发现:
- 点击自定义「Purchase」按钮弹出RevenueCat操作表后,若点击操作表关闭按钮或外部区域,
Purchases.shared.purchase的.purchaseCancelledError会正常触发回调; - 但点击操作表中的蓝色订阅按钮,完成支付后弹出「You're All Set」弹窗并点击OK按钮后,
purchase的回调完全没有触发,无法感知用户已完成订阅。
需要解决:如何正确检测用户完成订阅并点击OK的操作?
相关代码
func purchaseButtonTapped() { let productID = "..." Purchases.shared.getOfferings { [weak self](offerings, error) in guard let _ = error else { return } for dict in offerings.all { let offering = dict.value let packages = offering.availablePackages if let indexOfItem = packages.firstIndex(where: { $0.storeProduct.productIdentifier == productID }) { let pkg = packages[indexOfItem] self?.showSystemActionSheet(for: pkg) break } } } } func showSystemActionSheet(for package: Package) { Purchases.shared.purchase(package: package) { (transaction, customerInfo, error, userCancelled) in if let error = error as? RevenueCat.ErrorCode { switch error { case .purchaseCancelledError: // *** using breakpoints this gets hit when I cancel or dismiss the actionSheet return case .productAlreadyPurchasedError, .operationAlreadyInProgressForProductError, .receiptInUseByOtherSubscriberError : print("purchase is active") case .purchaseNotAllowedError: print("purchases_not_allowed") case .purchaseInvalidError: print("invalid_purchase_check_payment_method") default: break } return } if userCancelled { return } guard let customerInfo = customerInfo else { return } // after the user pressed Subscribe then pressed the OK button from the You're All Set alert, this print statement should get print/get hit with a break point but it never does print("the subscribe button and You're All Set alert was tapped") } }
解决方案
1. 修复getOfferings的逻辑错误
你代码里的getOfferings闭包存在致命逻辑反转:
原代码guard let _ = error else { return }的意思是没有错误时直接返回,导致后续查找目标package的逻辑完全不会执行。
正确写法应该是:有错误时才返回,无错误时继续执行后续流程。
2. 调整purchase回调的判断顺序
当前代码的错误处理分支末尾直接return,会覆盖成功场景的逻辑。需要把订阅成功的判断放在最前面,再依次处理取消状态和错误。
修正后的完整代码
修正purchaseButtonTapped
func purchaseButtonTapped() { let productID = "..." Purchases.shared.getOfferings { [weak self](offerings, error) in // 有错误时返回,无错误继续执行 guard error == nil else { print("获取Offerings失败: \(error?.localizedDescription ?? "")") return } guard let offerings = offerings else { return } for dict in offerings.all { let offering = dict.value let packages = offering.availablePackages if let indexOfItem = packages.firstIndex(where: { $0.storeProduct.productIdentifier == productID }) { let pkg = packages[indexOfItem] self?.showSystemActionSheet(for: pkg) break } } } }
修正showSystemActionSheet
func showSystemActionSheet(for package: Package) { Purchases.shared.purchase(package: package) { (transaction, customerInfo, error, userCancelled) in // 优先判断订阅成功 if let customerInfo = customerInfo { print("订阅完成,用户已确认") // 这里处理订阅成功后的业务逻辑,比如更新UI、跳转页面等 return } // 处理用户取消操作 if userCancelled { print("用户取消订阅流程") return } // 处理各类错误 if let error = error as? RevenueCat.ErrorCode { switch error { case .purchaseCancelledError: print("用户取消购买操作") case .productAlreadyPurchasedError, .operationAlreadyInProgressForProductError, .receiptInUseByOtherSubscriberError: print("订阅已处于激活状态") case .purchaseNotAllowedError: print("当前设备不允许购买,请检查设置") case .purchaseInvalidError: print("购买无效,请检查支付方式") default: print("购买出错:\(error.rawValue)") } } } }
3. 额外的订阅状态监听(可选)
为了避免遗漏订阅状态变化(比如用户通过其他渠道完成订阅),可以在App启动或页面初始化时注册全局监听:
// 注册用户信息更新监听 Purchases.shared.customerInfoUpdateHandler = { customerInfo in if !customerInfo.entitlements.active.isEmpty { print("用户当前有活跃订阅") // 同步更新本地UI或业务状态 } }
内容的提问来源于stack exchange,提问作者Lance Samaria
相关产品推荐
相关产品推荐

