Ian A McElhenny Ian A McElhenny - 1 year ago 66
Swift Question

How to make a post to a server, wait on the response, then change the view based on response in Swift?

I am trying to verify the user of my app when they open the app. I have a splash screen that sends a post of the users email to the sever and based on the response from the server it will either load the home view or an email verification page.

The problem I get is that when I make the post it seems to put it on its own separate thread, and I do not see the response until the view already changed and the app has settled.

I have tried to use:

NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue.mainQueue())


let task = session.dataTaskWithRequest(request)
//more stuff to handle return

and also


The problem with the first and third option is that they are deprecated methods, in addition to them working on their own thread, and receiving the response after the if statement changing the view already ran.

This is a snippet of the code being used:

//returns the email of the user
let email = self.fileCom.getUserStringField("email")

//write the string to post to the server
let post = "email=" + email +
"&pass=" + self.serverCom.PASSWORD

//post the user email to verification script and log result
logResponse(self.serverCom.postToServer(self.serverCom.getVerifyEmailScriptURL(), bodyData: post))

//Check the status of verified and email
// if(self.fileCom.getUserBoolField("verified"))
//change view to home view
//change view to verification view

The if statement to change the view is based on the stored response from the server to the user file in the documents folder.

Answer Source

NSURLSession is the current supported way to go here. With NSURLSession you can either create a class that implements its delegate methods to declare as its delegate, or you can use blocks/closures. "Blocks" in C/Obj-C closely map to "Closures" in Swift. They allow you to pass around functions as if they were variables. You can use NSURLSession's -dataTaskWithRequest:completionHandler: to accomplish this.

The completionHandler block will be executed (on the session's delegate queue) when the load completes. From there, you can act on the response.

Here is a quick example of using it (with some notes):

let task = NSURLSession.sharedSession().dataTaskWithRequest(request, completionHandler: {
// Don't put other code before this next line, it is defining the closure we just started with the "{"
(data, response, error) -> Void in
    // This is where the closure body begins
    print(NSThread.isMainThread()) // false (unless you've set the delegate queue to be the main queue)

    // Example of processing the return value
    let dataString = NSString.init(data: data!, encoding: NSUTF8StringEncoding)
    print(dataString) // Okay to do work with this here, but don't do any UI work.

    // Jump back over to the main queue to do any UI updates
    // UI updates must always be done on the main queue
    dispatch_async(dispatch_get_main_queue(), {
        print(NSThread.isMainThread()) // true (we told it to execute this new block on the main queue)
        // Execute the code to update your UI (change your view) from here

    // anything down here could be executed before the dispatch_async block completes
    // dispatch_sync would block this thread until its block completes

// run the task

// your program's main thread will not be blocked while the load is in progress