Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NSURLSessionTask. Suspend does not work

This is what Apple's documentation says regarding suspend method of NSURLSessionTask class

A task, while suspended, produces no network traffic and is not subject to timeouts.

Ok. So I'm running the following simple code:

        let url   = NSURL(string: "http://httpbin.org/delay/10")!
        let urlRequest = NSURLRequest(URL: url)

        self.task = NSURLSession.sharedSession().dataTaskWithURL(urlRequest.URL!, completionHandler: {

            data, response, error in print("completion ERROR \(error)")
        })

        self.task.resume()

        print("Start")
        delay(5, closure: {

            self.task.suspend()

            print("Suspend")
        })

Function delay is simply a wrapper around dispatch_after and a request to http://httpbin.org/delay/10 gives response after 10 seconds. In the middle of waiting for response I suspend the task. However that does not work. In 60 seconds the completion block is called with timeout error. Can anybody please explain what's wrong?

like image 989
Andrey Chernukha Avatar asked Nov 17 '16 18:11

Andrey Chernukha


1 Answers

This appears to be normal behaviour, however more definitive documentation from Apple would be useful in clarifying what we are seeing.

Apple’s documentation does not provide a detailed explanation of how suspend works, or when it should be used. However, my view (based on testing and research) is that suspend() should only be used for download tasks. Data tasks should only use resume() (to start the task) and cancel() when appropriate.

My testing, using Xcode and Charles Proxy, revealed a suspended data task has no effect on the network traffic as indicated in Apple’s documentation. In other words, network traffic is produced.

I observed two things using suspend and data tasks:

1) If it's called right after resume, it has no effect on the data task. It does not suspend network traffic and barring no network or server side-side issues, a successful response is received in the callback.

2) If it's called in the dispatch.asyncAfter callback, it still does not suspend the network traffic, however the callback gets a “request timeout” error instead of a successful response. According to Charles Proxy, the request is successful though. It is this result that leads me to believe that suspend() should not be be used with data tasks. The result of this callback is essentially useless in my opinion.

Cancelling a data task:

cancel() works as expected. The client (you) closes the connection before getting a complete response from the server. This can be done right after calling resume() or at a later time (before the request has completed of course).

like image 123
Ryan H. Avatar answered Sep 23 '22 16:09

Ryan H.