我有一个通过segue将视图控制器连接到另一个控制器的按钮,当按下时,将text
从UITextField
作为参数发送到AFNetwork
POST
请求并且必须决定segue是否可以继续,具体取决于请求是否成功。
所以我写了这个:
var proceed = false
let token = tokenTextField.text.trim()
let requestURL = "https://myapi.com/authenticate/"
// Make this a synchronous HTTP POST request so that we only decide whether
// to proceed with the segue or not once we know if the request was successful
manager.POST(requestURL,
parameters: [ "code" : token ],
success: { (operation: AFHTTPRequestOperation!, responseObject: AnyObject!) in
proceed = true
NSLog("Success! Response is \(responseObject.description)")
},
failure: { (operation: AFHTTPRequestOperation!, error: NSError!) in
println("Failure! Error is: \(error.localizedDescription)")
proceed = false
self.displayLoginAttempErrorAlert()
}).waitUntilFinished()
println("what a hard thing")
return proceed
但是此代码在"what a hard thing"
或success
回调中打印的任何内容之前打印error
,因此它显然是异步的。由于上面解释的原因,我希望它是同步的。我怎么能强迫这种行为?
请注意,请求本身没有任何问题。我只是想确保正确的事情顺序。
更新:我知道强迫事物同步可能会阻止用户界面,这对我来说很好。这就像一个登录屏幕,在发出请求和响应到达之间不应该发生任何事情。
提前致谢
答案 0 :(得分:3)
你可以:
completionQueue
的{{1}}指定为主队列以外的其他内容(这样当您阻止主线程时,您不会死锁,等待调用完成处理程序); manager
; dispatch_semaphore_semaphore
请求完成块内的信号量;和dispatch_semaphore_signal
请求后的信号量,但是从函数返回之前。但是,在我看来,使异步方法同步运行从根本上说是不正确的方法。它不仅是一个糟糕的用户体验,限制你的用户界面等,而且你也有可能让看门狗程序杀死你的应用程序。
我不是在dispatch_semaphore_wait
中使异步进程同步运行,而是采用标准的异步模式:
shouldPerformSegueWithIdentifier
执行异步请求,并且有一个完成块答案 1 :(得分:0)
为什么不在成功阻止中调用viewController
...我们也有相同的情况,其中用户有登录屏幕,而在验证失败的情况下,我们需要在成功时显示警告,将其重定向到{ {1}}。
如果您使用homeViewController
阻止,如果您只在队列中执行一个操作,它将与在成功阻止中处理它相同。
仍需要同步调用然后使用iOS的NSURLConnection类
queueCompletion