NSURLSessionConfiguration的timeoutIntervalForRequest无法与后台URLSession一起使用

时间:2018-06-27 12:23:58

标签: ios iphone timeout nsurlsession urlsession

我遵循了本教程Downloading files in background with URLSessionDownloadTask

还有这个苹果文档Downloading Files in the Background

我尝试设置是因为我们的API运行时间很长

let config = URLSessionConfiguration.background(withIdentifier: "\(Bundle.main.bundleIdentifier!).background")
    config.timeoutIntervalForRequest = 120
    config.timeoutIntervalForResource = 180

但是我碰到了这个奇怪的问题:

如果服务器未响应任何数据,则表示

func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didWriteData bytesWritten: Int64, totalBytesWritten: Int64, totalBytesExpectedToWrite: Int64)

根本不会被呼叫。

应用程序将终止先前的请求,并每66秒重试一个新请求。我不知道这个数字来自哪里,但是根据我的实验,大约是66秒

如果我对timeoutIntervalForRequest = 10的设置足够确定,则该应用将每10秒重试一次请求,但任何将其设置为66秒以上的尝试均无效

不确定是否有人遇到相同的问题并找到解决方案。

仅需注意1条:整个过程达到180秒时将超时,并且应用程序停止重试新请求

1 个答案:

答案 0 :(得分:1)

首先,这是一个错误。请提交到bugreport.apple.com。超时不应该那样被忽略。当然,这是一个电源管理问题并且不会得到解决,因此我绝不会屏息。

第二,即使解决了超时错误,您也可以通过一定的方式来解决问题。您的服务器没有发回任何字节以保持连接正常的事实当然是iOS设备断开连接的原因,但是即使您进行了更改并使其每次每次都发送一个伪造的头一个字节,在数据准备好五秒钟之前,您仍然会遇到问题。

基本上,在移动设备上,无论出于任何原因,您实际上都不应该保持与远程服务器的长时间运行的连接打开。连续浪费Wi-Fi无线电,大大浪费了电池,更不用说蜂窝无线电了,更糟的是,当用户走出范围,切换蜂窝站点或暂时失去连接时,该连接随时可能失败。网络简直是垃圾,蜂窝网络则是如此。

用于长时间运行的服务器处理的一种更好的方法是异步进行处理:

  • 向服务器发送请求。
  • 让服务器发回给您与请求关联的唯一标识符,以及可选的估计完成时间。
  • 等待直到估计的完成时间,然后询问服务器运行情况(提供唯一标识符)。
  • 继续定期轮询服务器,直到服务器说任务完成(或失败)为止。
  • 服务器说任务已完成时,发出请求以检索结果,然后发出请求以释放完成的结果。
  • 使用cron作业或类似方法定期清除服务器上未收集的旧结果。

这种方法避免了使无线电保持热点,除了在轮询请求的两边都有几秒钟的时间之外,这使超时问题完全没有意义。