“等待”Swift中的任务结果

时间:2017-02-28 15:54:46

标签: asynchronous swift3 async-await alamofire grand-central-dispatch

我来自C#背景,并希望在我的Swift应用程序中实现等待功能。我已经达到了我想要的结果,但我不得不使用一个信号量,我不确定它是不是很好的做法。我有一个带有alamo请求的函数,它返回一个带有成功值的JSON,据我所知,请求函数与完成处理程序是异步的。请求完成后,处理程序将触发。问题是从该操作返回成功值。这是我正在做的伪代码示例:

func AlamoTest() -> Bool{
var success = false
//Do some things...
//...
//Signal from async code
let semaphore = DispatchSemaphore(value: 0)
Alamofire.request("blah blah blah", method: .post, parameters: parameters, encoding: URLEncoding.default).responseJSON { response in {
    success = response["success"]
    if(success){
        //Do some more things
    }
    semaphore.signal() //Signal async code is done
}
//Wait until async code done to get result
semaphore.wait(timeout: DispatchTime.distantFuture)
return success
}

有没有“更好”的方式来实现我的目标?我是Swift及其异步构造的新手。

2 个答案:

答案 0 :(得分:0)

我找到的最佳解决方案就是我所说的"回调链接"。我的方法示例如下所示:

func postJSON(json: NSDictionary, function: ServerFunction, completionHandler: ((_ jsonResponse: NSDictionary) -> Void)? = nil) {
    //Create json payload from dictionary object
    guard let payload = serializeJSON(json: json) else {
        print("Error creating json from json parameter")
        return
    }

    //Send request
    Alamofire.request(urlTemplate(function.rawValue), method: .post, parameters: payload, encoding: URLEncoding.default).validate().responseJSON { response in
        //Check response from server
        switch response.result {
            case .success(let data):
                let jsonResponse = data as! NSDictionary
                print("\(jsonResponse)")
                //Execute callback post request handler
                if completionHandler != nil {
                    completionHandler!(jsonResponse)
                }
            case .failure(let error):
                    print("Shit didn't work!\(error)")
            }
    }
}

最后一个参数是在原始异步操作完成后执行的闭包。您将结果传递给闭包,并使用它执行您想要的操作。在我的情况下,我想在异步操作滚动时禁用视图。您可以在闭包参数中启用视图,因为在主线程上调用了alamo异步操作的结果。如果你不需要结果并停止链接,则completionHandler默认为nil。

答案 1 :(得分:0)

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

func AlamoTest() throws -> Bool {
    try Coroutine.await() { callback in
        Alamofire.request("blah blah blah", method: .post, parameters: parameters, encoding: .default).responseJSON { response in
            let success = response["success"]
            callback(success)
        }
    }
}

,然后在协程内部调用此方法:

DispatchQueue.main.startCoroutine {
    let result = try AlamoTest()

}