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

使用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 08:22:51