ios - 正确配置闭包以捕获结果

标签 ios swift closures

我正在编写一些用于应用内购买的自定义商店方法;有点像 SwiftyStore 的包装器。我遇到的问题是无法在关闭之前获取结果。

关于如何正确设置它们有什么建议吗? IE:关闭...

我有一个函数,可以检查现有订阅,如果在 firebase 中找到订阅,则返回 true,如果没有,则它会前往苹果商店验证之前购买的订阅:

func checkSubscription() -> Bool {
        var RetVal: Bool = false
        var retStat: String = ""
        var myVal: Bool = false

        self.rootRef.child("users").child(self.userID!).observeSingleEvent(of: .value, with: { (snapshot) in
            // Get user value
            let value = snapshot.value as? NSDictionary
            let mySubType = value?["subtyp"] as? String ?? ""
            // set value
            if mySubType == "" {
                // get receipt
                if self.myStore.getReceipt() == true {
                    (myVal, retStat) = self.myStore.verifyPurchase(product: "com.xxxxx.xxxxx.monthly")
                    if myVal == true && retStat == "Valid" {
                        // we have a valid product update firebase
                        print("Valid")
                    } else if myVal == true && retStat == "Expired" {
                        // we have a valid product that is expired
                        print("Expired")
                    }
                }
            } else {
                // we have a purchase, verify its not expired.
                print("Purchased")
                RetVal = true
            }

        }) { (error) in
            print(error.localizedDescription)
        }
        return RetVal
    }

这里的问题是它在闭包完成之前下降到返回 RetVal,因此该函数可能返回无效值。不确定如何在当前设置中解决此问题,但任何建议或指示将不胜感激。

最佳答案

为了扩展 Tom 的评论,如果您想在嵌套异步函数完成时返回结果,您可以传入一个使用 Swift 提供的 Result 类型的完成处理程序闭包,如下所示:

func checkSubscription(completion: @escaping (Result<Bool, Error>) -> Void) {
    var RetVal: Bool = false
    var retStat: String = ""
    var myVal: Bool = false

    self.rootRef.child("users").child(self.userID!).observeSingleEvent(of: .value, with: { (snapshot) in
        // Get user value
        let value = snapshot.value as? NSDictionary
        let mySubType = value?["subtyp"] as? String ?? ""
        // set value
        if mySubType == "" {
            // get receipt
            if self.myStore.getReceipt() == true {
                (myVal, retStat) = self.myStore.verifyPurchase(product: "com.xxxxx.xxxxx.monthly")
                if myVal == true && retStat == "Valid" {
                    // we have a valid product update firebase
                    print("Valid")
                } else if myVal == true && retStat == "Expired" {
                    // we have a valid product that is expired
                    print("Expired")
                }
            }
        } else {
            // we have a purchase, verify its not expired.
            print("Purchased")
            RetVal = true
        }

        completion(.success(RetVal))

    }) { (error) in
        print(error.localizedDescription)
        completion(.failure(error))
    }
}

使用这种类型的完成处理程序调用函数将如下所示:

checkSubscription { (result) in
    switch result {
    case .success(let boolValue):
        // do something with resulting boolean
        break
    case .failure(let error):
        // do something with resulting error
        break
    }
}

关于ios - 正确配置闭包以捕获结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59057903/

相关文章:

Javascript 闭包问题

字符串和不可初始化类的 PHP instanceof

reference - 当函数需要引用闭包参数时,如何将函数用作闭包?

iphone - 如何保存来自不同 View Controller 的数据并将其加载到 iOS 中的另一个 View Controller 中

ios - 无法识别的选择器发送到 UITableView 内的实例

ios - UIScrollView 的 subview 保持在同一位置,而 UIScrollView 垂直滚动

ios - CoreBluetooth 中心在指定服务时未发现任何外围设备

java - LibGdx 无法在 iOs 模拟器上启动应用程序

ios - 在相机捕获和图像编辑时使用 GPUImage GaussianSelective Blur Filter

ios - 不能在 inout 函数中使用 SKShapeNode