【问题标题】:Swift write an async/await method with return valueSwift 编写一个带返回值的 async/await 方法
【发布时间】:2019-09-14 12:28:02
【问题描述】:

我想编写一个带返回值的异步等待方法,但我的代码不起作用。我还尝试了另一种方式,例如DispatchQueue.globalDispatchGroup()等等。
这是我的代码:

func checkPassCode() -> Bool {

        var result = false

        let closure = { (_ flag:Bool) -> Void in
            result = flag
        }

        if var pin = self.keychain.get("pin") {
            let userPin = self.pin.joined(separator: "")
            let encryptedData = NSData(base64Encoded: pin, options: [])

            AsymmetricCryptoManager.sharedInstance.decryptMessageWithPrivateKey(encryptedData! as Data) { (success, result, error) -> Void in
                if success {
                    pin = result!
                    print("userPin is: \(userPin)")
                    print("storePin is: \(pin)")
                    closure(userPin == pin)
                } else {
                    print("Error decoding base64 string: \(String(describing: error))")
                    closure(false)
                }
            }
        }
        return result
    }

【问题讨论】:

  • 真的,不要这样做。将闭包传递给您的函数,以便在异步任务完成后调用。
  • @Paulw11 有没有通过闭包解决的另一种方法?我也想写简单。
  • 您尚未准确描述“不起作用”的内容,但您似乎正在死锁主队列。接受异步任务是 iOS 开发的基本部分。闭包在 iOS 编程中非常简单且易于理解
  • @Paulw11是的,你说得对,我正在使主队列陷入僵局。我认为如果传递一个闭包,那么我必须为每个方法调用声明一个闭包,对吗?
  • @Paulw11我用闭包定义改变了我的代码

标签: ios swift asynchronous async-await dispatch


【解决方案1】:

谢谢,vadian 评论。我使用闭包作为方法的输入参数。

// MARK: - PassCode Methods
func checkPassCode(completionHandler:@escaping (_ flag:Bool) -> ()) {
    let storePin = getStorePin()
    let userPin = self.pin.joined(separator: "")
    AsymmetricCryptoManager.sharedInstance.decryptMessageWithPrivateKey(storePin as Data) { (success, result, error) -> Void in
        if success {
            let pin = result!
            print("userPin is: \(userPin)")
            print("storePin is: \(pin)")
            completionHandler(userPin == pin)
        } else {
            print("Error decoding base64 string: \(String(describing: error))")
            completionHandler(false)
        }
    }
}

func getStorePin() -> NSData {
    if let pin = self.keychain.get("pin") {
        return NSData(base64Encoded: pin, options: []) ?? NSData()
    }
    return NSData()
}

然后调用这个方法:

checkPassCode { success in
                    if success {
                        print("sucess")
                    } else {
                        print("not sucess!")
                    }
                }

【讨论】:

    【解决方案2】:

    您可以将此框架用于 Swift 协程 - https://github.com/belozierov/SwiftCoroutine

    当你调用 await 时,它不会阻塞线程,只会挂起协程,所以你也可以在主线程中使用它。

    func awaitCheckPassCode() throws -> Bool {
        let storePin = getStorePin()
        let userPin = self.pin.joined(separator: "")
        let manager = AsymmetricCryptoManager.sharedInstance
        let (success, result, _) = try Coroutine.await {
            manager.decryptMessageWithPrivateKey(storePin as Data, completion: $0)
        }
        return success && userPin == result
    }
    

    然后在协程内部调用这个方法:

    DispatchQueue.main.startCoroutine {
        let success = try awaitCheckPassCode()
    
        if success {
            print("sucess")
        } else {
            print("not sucess!")
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2017-12-20
      • 2016-12-12
      • 1970-01-01
      • 2014-11-01
      • 2013-02-27
      • 2020-09-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多