如何等待 swift 中 POST 调用的结果?

How can I wait for the result of the POST call in swift?

我正在使用 google api for ios 登录移动应用程序(取自此处:https://developers.google.com/identity/sign-in/ios/backend-auth 他们在那里展示了如何使用 objective-c 向后端服务器发出 post 请求,结果是获取令牌是否有效的信息。

我正确地建立了我的后端服务器,它验证令牌是否正确(并且它 returns 状态 200401。现在我只需要发送从应用程序到我的服务器的令牌,并根据其结果验证用户与否。

我找到了关于发出 post 请求的答案:

按照这个例子,我将其编码如下:

// [START signin_handler]
func signIn(signIn: GIDSignIn!, didSignInForUser user: GIDGoogleUser!,
    withError error: NSError!) {
        if (error == nil) {
            print("!!!! TOKEN !!!! "+user.authentication.idToken)

            let request = NSMutableURLRequest(URL: NSURL(string: "http://mywebserver.com:3000/auth/token")!)
            request.HTTPMethod = "POST"
            let postString = "id_token="+user.authentication.idToken
            request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding)
            let task = NSURLSession.sharedSession().dataTaskWithRequest(request) { data, response, error in
                guard error == nil && data != nil else {                                                          // check for fundamental networking error
                    print("error=\(error)")
                    return
                }

                if let httpStatus = response as? NSHTTPURLResponse where httpStatus.statusCode != 200 {           // check for http errors
                    print("statusCode should be 200, but is \(httpStatus.statusCode)")
                    print("response = \(response)")
                }

                let responseString = NSString(data: data!, encoding: NSUTF8StringEncoding)
                print("responseString = \(responseString)")


                print("Signed in as a user: "+user.profile.name)

            }
            task.resume()

            let sb = UIStoryboard(name: "Main", bundle: nil)
            if let tabBarVC = sb.instantiateViewControllerWithIdentifier("TabController") as? TabController {
                self.window!.rootViewController = tabBarVC
            }

        } else {
            print("\(error.localizedDescription)")

        }
}
// [END signin_handler]

好的,在这种情况下,在调用网络服务后,我立即将视图切换到应用程序的主页:

let sb = UIStoryboard(name: "Main", bundle: nil)
                if let tabBarVC = sb.instantiateViewControllerWithIdentifier("TabController") as? TabController {
                    self.window!.rootViewController = tabBarVC
                }

但是由于我是在 task.resume() 之后立即执行的 - 这意味着我永远不会等待网络服务的结果,即使它声明 401 - 用户仍然签署了它。我试图将那段代码放在 task.resume() 之上,但随后出现错误:

This application is modifying the autolayout engine from a background thread, which can lead to engine corruption and weird crashes.  This will cause an exception in a future release.

那么我如何在登录过程中包含来自我的网络服务的答案,如果状态是 200 - 然后将视图切换到我的 TabController? (在其他情况下,例如要求用户重新登录)

告诉,不要等待。

请求异步工作,因此成功时在完成块中实例化您的控制器。要避免 auto layout engine 消息,您必须在主线程上执行此操作。

       ...
       print("Signed in as a user: "+user.profile.name)

       dispatch_async(dispatch_get_main_queue()) {
          let sb = UIStoryboard(name: "Main", bundle: nil)
          if let tabBarVC = sb.instantiateViewControllerWithIdentifier("TabController") as? TabController {
            self.window!.rootViewController = tabBarVC
          }
       }
     }
     task.resume()
   } else { ... }