强制 AFNetwork POST 请求同步

Force AFNetwork POST request to be synchronous

我有一个按钮,通过 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

但是此代码在 successerror 回调中打印任何内容之前打印 "what a hard thing",因此它显然是异步的。由于上面解释的原因,我希望它是同步的。我怎样才能强迫这种行为?

请记住,请求本身没有任何问题。我只是想确保事物的正确顺序。

UPDATE:我知道强制同步可能会阻塞 UI,这对我来说很好。这就像一个登录屏幕,在发出请求和响应到达之间不应发生任何事情。

提前致谢

您可以:

  • 指定managercompletionQueue为主队列以外的东西(这样在阻塞主线程等待调用完成处理程序时就不会死锁);
  • dispatch_semaphore_semaphore 开始请求之前;
  • dispatch_semaphore_signal 请求完成块内的信号量;和
  • dispatch_semaphore_wait 用于请求之后的信号量,但在您 return 从您的函数之前。

但在我看来,让异步方法同步运行从根本上说是不正确的方法。它不仅是一个糟糕的用户体验,限制了你的 UI 等,而且你还有被看门狗进程杀死你的应用程序的风险。

与其让异步进程在 shouldPerformSegueWithIdentifier 中同步运行,不如采用标准的异步模式:

  • 从 UIKit 控件中删除您可能拥有的现有 segue 到下一个场景;
  • 在视图控制器之间创建一个新的 segue(如 shown here),它不会自动执行,而只能以编程方式执行(见下文);
  • 有一个执行异步请求的 IBAction,并且有一个
  • 的完成块
  • 根据需要以编程方式启动 segue。

你为什么不在成功块中调用你的 viewController...我们也有同样的情况,用户有一个登录屏幕,如果发生身份验证失败,那么我们需要显示警报,否则在成功时重定向它至 homeViewController

如果您使用 queueCompletion 块,如果您只在队列中执行一个操作,它将与在成功块中处理它相同。

仍然需要同步调用然后使用 iOS

的 NSURLConnection class
-[NSURLConnection sendSynchronousRequest:returningResponse:error]