【问题标题】:How can I wait for the result of the POST call in swift?如何快速等待 POST 调用的结果?
【发布时间】:2016-05-24 17:36:29
【问题描述】:

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

我正确建立了我的后端服务器,它会验证令牌是否良好(它返回状态 200 或 401。现在我只需要将令牌从应用程序发送到我的服务器并基于其结果是否验证用户。

我找到了有关发出帖子请求的答案:https://stackoverflow.com/a/26365148/4662074

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

// [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]

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

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? (在其他情况下,例如要求用户再次登录)

【问题讨论】:

    标签: ios swift google-signin


    【解决方案1】:

    告诉,不要等待。

    请求异步工作,因此在成功时在完成块中实例化您的控制器。要避免 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 { ... }
    

    【讨论】:

    • 好的,谢谢,这是有道理的,但我知道只有当状态为 200 时我才必须这样做 - 你能告诉我,根据我的代码,我该如何检查它?跨度>
    • 只需在检查响应代码时添加一个return 语句,就像在guard 表达式中一样。
    • 对不起,如果这是一个乏味的问题,我在 print("response = \(response)") 之后添加了 return 但现在当我想在稍后的 if 语句中包含 httpStatus 时,我得到了 use of unresolved value httpStatus - 什么我做错了吗?
    • 使用guard let httpStatus = response as? NSHTTPURLResponse where httpStatus.statusCode != 200 else { print .. return }
    猜你喜欢
    • 2021-08-17
    • 1970-01-01
    • 2019-08-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多