dataTaskWithRequest problem - can't debug it

hi all,

I have the following method I converting from swift 1.2 to swift 2.0 and had to change the code to use NSURLSession since NSURLConnection is not supported anymore.


following the new code:

func isSessionEnabledForUsername(theUsername: String,completion: ((success:Bool, error:NSError!) -> Void)!) {

let url = NSURL(string: "http:/.....")

let request: NSURLRequest = NSURLRequest(URL: url!)

let config = NSURLSessionConfiguration.defaultSessionConfiguration()

let session = NSURLSession(configuration: config)


let task : NSURLSessionDataTask = session.dataTaskWithRequest(request, completionHandler: {(responseData, response, error) in

let statusCode = self.loadStatusCode(response!)

if statusCode == 403 {

completion(success:false, error:error)

return

} else if (statusCode >= 200 && statusCode < 400 )

{

completion(success:true, error:error)

return

}

}) /

task.resume()

completion(success:true, error: nil)

return

}


the code is not working as expected and for some reason when I try to debug it, I cant get to the line inside the session.dataTaskWithRequest enclosure:

let statusCode = self.loadStatusCode(response!)

the compiler jump me directly to the end of the enclosure: })


any idea what I'm doing wrong?

thanks in advance

That closure is a completion hander, which means it won't execute until the reqeust is complete. If you put a breakpoint on that line, it should stop there when the request is completed.

Why do you call completion block at the end of the method? It gets called before the request completes.

Accepted Answer

After further investigation in the documentation I realized session.dataTaskWithRequest is highly asyncronous, and since I need the funcions to be syncronous, I modified my code as following and it worked for me, so I'm publishing it here so maybe it could help others...


func isSessionEnabledForUsername(theUsername: String,completion: ((success:Bool, error:NSError!) -> Void)!){

let url = NSURL(string: "http:/...")

let request: NSURLRequest = NSURLRequest(URL: url!)

let config = NSURLSessionConfiguration.defaultSessionConfiguration()

let session = NSURLSession(configuration: config)

var statusCode = -1

let group = dispatch_group_create()

dispatch_group_enter(group)

session.dataTaskWithRequest(request, completionHandler: {responseData, response, error -> Void in

if let httpResponse = response as? NSHTTPURLResponse {

statusCode = httpResponse.statusCode

}

dispatch_group_leave(group)

}).resume()

dispatch_group_wait(group, DISPATCH_TIME_FOREVER)

if statusCode == 403 {

completion(success:false, error:nil)

return

} else if (statusCode >= 200 && statusCode < 400 )

{

completion(success:true, error:nil)

return

}

completion(success:true, error: nil)

return

}

I, and maybe many other developers including Apple Staff, strongly recommend you NOT to make the method synchronous.

If you call the method from within the UI thread, it may block processing the UI thread, which casuses a bad response for users.


As guywithmazda suggested, you can debug the completion handler if you just put a breakpoint inside the closure, such as on the line let statusCode = self.loadStatusCode(response!).


Back to the asynchronous version and understand the usage of asynchronous methods.

Your method is already passing a completion block as a parameter so it seems you are handling the response asynchronously...

Your method is already passing a completion block as a parameter so it seems you are handling the response asynchronously...

Yeah, that’s the bit I don’t understand.

Can you post your old NSURLConnection code so we can see what it did?

Share and Enjoy

Quinn "The Eskimo!"
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"
dataTaskWithRequest problem - can't debug it
 
 
Q