1

I have a Login View Controller, and an Other View Controller. What I'd like to do is: when the user hits login, it sends their credentials to the remote server. The remote server returns a response indicating whether the credentials were good or not, and if they were good, the app redirects to the Other View Controller.

The code below crashes at the call to .performSegueWithIdentifier.

The crash gives an error code of EXC_BAD_ACCESS(code=1, address=0xbbadbeef)

Question: what is the swifty way of doing this?

var request = NSMutableURLRequest(URL: NSURL(string: "http://url.to/my/login/handler")!)
var session = NSURLSession.sharedSession()
request.HTTPMethod = "POST"

//user initialized earlier
bodyData = "email=\(user.username)&password=\(user.password)"

request.HTTPBody = bodyData.dataUsingEncoding(NSUTF8StringEncoding);

var task = session.dataTaskWithRequest(request, completionHandler: {data, response, error -> Void in
    // check that log in was successful by looking in 'response' arg
    // if login was successful
    self.performSegueWithIdentifier("SegueToOtherController", sender: self)
    }
task.resume()
}
jonesjones
  • 477
  • 1
  • 6
  • 13

1 Answers1

0

If it's crashing, you should share the details the crash in order to identify why. Likely problems include that it didn't find a segue of that identifier as the "storyboard id" from the current view controller to the next scene. But it's impossible to say without details on the precise error.

Having said that, there is another problem here: The completion block may not run on the main thread, but all UI updates must happen on the main thread. So make sure to dispatch that back to the main queue, e.g.

let request = NSMutableURLRequest(URL: NSURL(string: "http://url.to/my/login/handler")!)
let session = NSURLSession.sharedSession()
request.HTTPMethod = "POST"

//user initialized earlier
bodyData = "email=\(user.username)&password=\(user.password)"

request.HTTPBody = bodyData.dataUsingEncoding(NSUTF8StringEncoding);

let task = session.dataTaskWithRequest(request) {data, response, error in
    // check that log in was successful by looking in 'response' arg
    // if login was successful
    dispatch_async(dispatch_get_main_queue()) {
        self.performSegueWithIdentifier("SegueToOtherController", sender: self)
    }
}
task.resume()

Note, I also changed all of those var references to let (as a general rule, use let wherever possible). Also, I haven't tackled it here, but you really should be percent escaping the username and password properties. If, for example, the password included any reserved characters like + or &, this would fail. There are lots of ways of doing that, e.g. something like the method discussed here: https://stackoverflow.com/a/26317562/1271826 or https://stackoverflow.com/a/25154803/1271826.

Community
  • 1
  • 1
Rob
  • 415,655
  • 72
  • 787
  • 1,044
  • Thank you! That worked. For future googlers, the error looked like this: EXC_BAD_ACCESS(code=1, address=0xbbadbeef) ps thanks, re the lets and percent escaping – jonesjones Apr 26 '15 at 03:10