NSURLSessionTask. Suspend无法工作。

8
这是苹果文档关于NSURLSessionTask类的“暂停”方法的说明:

任务在暂停期间不会产生任何网络流量,并且不会受到超时限制。

好的。所以我正在运行以下简单代码:
        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")
        })

delay函数只是对dispatch_after的简单封装,而对http://httpbin.org/delay/10的请求将在10秒后得到响应。在等待响应期间,我暂停了任务。但这并不起作用。在60秒内,完成块被调用并报告超时错误。有人可以解释一下问题出在哪里吗?


你能展示一下 dispatch_after 的包装器吗? - Ryan H.
3个回答

7
这似乎是正常行为,但我们需要更权威的苹果文档来澄清我们所看到的内容。
苹果文档没有提供有关暂停操作如何工作或何时使用它的详细说明。然而,我的观点(基于测试和研究)是,suspend() 应仅用于下载任务。数据任务应只使用 resume()(启动任务)和在适当时使用 cancel()
我的测试使用 Xcode 和 Charles Proxy,结果显示暂停的数据任务对网络流量没有影响,这与苹果文档中的说明相符。换句话说,会产生网络流量。
我使用 suspend 和数据任务时观察到了两件事情:
1)如果在恢复后立即调用,它不会对数据任务产生影响。它不会暂停网络流量,并且在没有网络或服务器问题的情况下,回调函数会收到成功的响应。
2)如果在 dispatch.asyncAfter 回调中调用,它仍然不能暂停网络流量,但回调函数会收到“请求超时”错误而非成功的响应。根据 Charles Proxy 的记录,请求实际上是成功的。这种结果使我认为不应该使用 suspend() 来处理数据任务。这个回调的结果在我看来是没有用的。
取消数据任务: cancel() 的表现与预期相符。客户端(您)在服务器发送完完整响应之前关闭连接。这可以在调用 resume() 后立即完成,或在稍后时刻完成(当然,在请求完成之前)。

"请求超时。"是什么意思?错误传递到完成块中了吗?所以它对你和我都有效,因此对于挂起的任务来说这是正常行为,对吗?如果是的话,那我们为什么需要挂起呢?还是我理解错了什么?" - Andrey Chernukha
@AndreyChernukha 对不起,看来我误解了你的问题。我以为你在控制台上没有看到“挂起”消息。 - Ryan H.
@AndreyChernukha,您说得对。我更新了我的回答,以提供更多细节。这似乎是数据任务的正常行为。下载任务应该不会在恢复和完成任务之前传递到完成块。 - Ryan H.

0

您可以使用URLRequest调用dataTask,并将timeoutInterval设置为.infinity。(默认为60秒)

var request = URLRequest(url: url)
request.timeoutInterval = .infinity
task = session.dataTask(with: request)
task?.resume()

0

我知道在URLSessionDataTask中调用suspend()方法没有任何效果。

                    let dataTask = URLSession.shared.dataTask(with: request) { (data, urlResponse, error) in                        
                    print("response is received all the time")
                    }
                }
                dataTask.resume()
                dataTask.suspend()

然而,当我尝试取消它时。

let dataTask = URLSession.shared.dataTask(with: request) { (data, urlResponse, error) in                        
                    print("response is cancelled")
                    }
                }
                dataTask.resume()
                dataTask.cancel()

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接