1

I’m trying to migrate to NSURLSession from NSURLConnection. I’ve used delegate methods to return the JSON object IN NSURLConnection previously. But now I’m looking to implement blocks to return the JSON object. I have my own block to return the JSON object since I have NSURLSession Network Aactivity in a separate class common to all service calls. I ahve use its delegate methods and everything is working fine but when I use its in-built block to get the object and return it using my own block thats when things get messy.

I've searched through web and found people using GCD to get the mainqueue and invoking the return block. I tried that too but sometimes it gets delayed too. What is the best practice to do this?

Here's my code

let urlString = baseURL + methodName
let postString = NSString(bytes: postData.bytes, length: postData.length, encoding: NSUTF8StringEncoding)

let request : NSMutableURLRequest = NSMutableURLRequest(URL: url)
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.HTTPMethod = "POST"
request.HTTPBody = postString?.dataUsingEncoding(NSUTF8StringEncoding)
request.timeoutInterval = requestTimeOutInterval

let task = NSURLSession.sharedSession().dataTaskWithRequest(request, completionHandler: {data, response, error -> Void in
                    NSURLSession.sharedSession().finishTasksAndInvalidate()

                    do {
                        let responseDict: NSMutableDictionary? = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.AllowFragments) as? NSMutableDictionary

                        dispatch_async(dispatch_get_main_queue()) {
                            completionHandler(responseDict, nil, true)
                        }

                    } catch let err as NSError {
                        dispatch_async(dispatch_get_main_queue()) {
                            completionHandler(nil, nil, true)
                        }
                    }
})

task.resume()
Mihir Oza
  • 2,768
  • 3
  • 35
  • 61
Matt
  • 1,711
  • 18
  • 20
  • Why are you calling `finishTasksAndInvalidate()` ? – nswamy Oct 23 '15 at 06:54
  • `finishTasksAndInvalidate()` method invalidates the session. For every call you are creating a session object and thats the reason ur seeing the delay. – nswamy Oct 23 '15 at 06:59
  • I read in a tutorial a while ago that its best to do that, the task will only pause when it completes does not deactivate. – Matt Oct 23 '15 at 06:59
  • @nanjunda but the delay does not happen everytime – Matt Oct 23 '15 at 07:00
  • should i leave the task open? – Matt Oct 23 '15 at 07:01
  • Not sure if you really need it. Since your are using `NSURLSession.sharedSession` for all ur request. Try removing the method call `finishTasksAndInvalidate` – nswamy Oct 23 '15 at 07:03
  • `finishTasksAndInvalidate()` acts on session not on Task. Once completion handler is called the task will be marked complete and you dont have to worry about it. – nswamy Oct 23 '15 at 07:06
  • I gave it a try and its working. Should I even have to use finishTasksAndInvalidate() anywhere in my app? – Matt Oct 23 '15 at 07:09
  • If you are creating your own Session, you may need it else no. – nswamy Oct 23 '15 at 07:10

1 Answers1

0

finishTasksAndInvalidate() acts on session not on Task. Once completion handler is called the task will be marked complete and you dont have to worry about it.

nswamy
  • 1,041
  • 9
  • 16
  • And thats because I use NSURLsession. sharedSession() directly? – Matt Oct 23 '15 at 08:17
  • do I have to tweak GCD for efficiency or leave it as it is? – Matt Oct 23 '15 at 08:18
  • Yes, as ur using it directly. If your completion block is called in Main thread you can remove GCD block, even if its present it will not harm you :) – nswamy Oct 23 '15 at 08:27