NSURLSessionDownloadTask 在后台自动恢复所有任务

NSURLSessionDownloadTask resumes automatically all task while in background

我需要按顺序下载文件。目前我可以在应用程序处于前台时执行此操作。

以下是我使用的逻辑。

  1. 创建所有下载任务。

  2. 一次恢复一个,当前完成后从 URLSession:task:didCompleteWithError: 恢复下一个。

此逻辑在应用程序处于前台时有效,但一旦应用程序开始 运行 在后台(通过崩溃)并且我们再次 运行 应用程序在下载完成之前完成所有任务状态已更改恢复并且所有都在同时下载。

这是预期的行为还是我在后台模式下连续订购它所缺少的任何东西?

编辑: 我通过一个一个地创建下载任务来检查。完成第一个任务后在 setTaskDidCompleteBlock 中创建下一个,依此类推。它只完成第一个任务,然后在 setTaskDidCompleteBlock 中创建任务时会话崩溃(这仅在 运行 在后台模式下发生,因为前台工作正常)。

这是我的崩溃日志屏幕截图:

如有任何帮助,我们将不胜感激。

如果你绝对需要按顺序运行这些请求,我建议不要预先实例化所有这些任务,而是一次实例化它们,只在完成时实例化下一个任务前一个。

但我们必须认识到,您会因 运行顺序处理请求而付出显着的性能损失。 (当使用后台会话时,这个问题会被放大。)如果可能的话,看看你是否可以同时将你的请求更改为 运行。显然,如果您需要一个的输出以便为另一个创建请求,那么您就会陷入困境(或者至少在您重构服务器代码之前),但这显然不是这里的问题(因为您创建了所有请求正面)。如果您出于人为原因执行此顺序请求过程(例如,代码正在填充数组并且您希望按顺序排列),那么您可能需要重新设计实现以删除此人为约束。

我也看到过这种情况。如果您在应用程序处于前台时创建了一个 downloadTask 但不调用 resume(),它不会启动 — 但是,它会在应用程序处于后台时自动启动。

解决方案是在创建每个 downloadTask 时显式调用 suspend()。然后,当您准备好开始下载时,请调用 resume()

显然新创建的 downloadTask 既没有暂停也没有恢复。它的初始状态不是 .Running,但当应用程序进入后台时,它会变为 .Running,因为它没有被明确挂起。这是令人惊讶的行为;我不知道为什么后台会话守护进程会这样工作。