我怎样才能在swift中等待POST调用的结果?

时间:2016-02-13 15:38:02

标签: ios swift google-signin

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

我正确建立了我的后端服务器并验证令牌是否正常(并返回状态200401。现在我只需要将应用程序中的令牌发送给我服务器并根据其结果验证用户与否。

我找到了关于发布帖子请求的答案: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]

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

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

1 个答案:

答案 0 :(得分:1)

告诉,不要等。

请求异步工作,因此成功时在完成块中实例化控制器。要避免 ... 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 { ... } 消息,您必须在主线程上执行此操作。

# Import django modules
from django.shortcuts import render_to_response
from django.template.loader import render_to_string
from django.http import HttpResponse
import simplejson
from waypoints.models import Waypoint

def save(request):
'Save waypoints'
for waypointString in request.POST.get('waypointsPayload', '').splitlines():
    waypointID, waypointX, waypointY = waypointString.split()
    waypoint = Waypoint.objects.get(id=int(waypointID))
    waypoint.geometry.set_x(float(waypointX))
    waypoint.geometry.set_y(float(waypointY))
    waypoint.save()
return HttpResponse(simplejson.dumps(dict(isOk=1)),    mimetype='application/json')