我来自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及其异步构造的新手。
答案 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()
}