NSURLSession 后台下载 - 通过网络故障恢复

Posted

技术标签:

【中文标题】NSURLSession 后台下载 - 通过网络故障恢复【英文标题】:NSURLSession background download - resume over network failure 【发布时间】:2013-10-11 15:28:27 【问题描述】:

在阅读了有关使用新 ios7 api (NSURLSession) 进行后台下载的 Apple 文档后,我有点失望。我确信 Apple 正在后台管理网络可用性的暂停/恢复(或提供这样做的选项),但没有……

所以阅读文档,这就是我们所拥有的:

https://developer.apple.com/library/ios/documentation/cocoa/Conceptual/URLLoadingSystem/NSURLSessionConcepts/NSURLSessionConcepts.html

当任何任务完成时,NSURLSession 对象调用 委托的 URLSession:task:didCompleteWithError: 方法 错误对象,如果任务成功完成,则返回 nil。 如果任务是可恢复的下载任务,则 NSError 对象的 userInfo 字典 包含 NSURLSessionDownloadTaskResumeData 键的值。您的 应用程序应使用可达性 API 来确定何时重试,以及 然后应该调用 downloadTaskWithResumeData: 或 downloadTaskWithResumeData:completionHandler: 创建一个新的下载 任务以继续下载。转到第 3 步(创建和恢复 任务对象)。

到目前为止我了解解决方案,但我的问题是:什么架构最适合处理网络丢失并在后台恢复下载?

就我而言,我使用的是可达性,每次网络可用时,我都会恢复所有任务(在创建时通过 NSArray 引用),并在网络丢失时暂停它们。这在前台效果很好,但对于后台我需要以下几点帮助:

如果我的应用在前台没有连接,如果我在没有连接的情况下进入后台,我的所有任务都将保持暂停状态,并且在网络可用时不会返回......

在后台丢失网络,停止我所有的下载/任务。 场景:

在前台,我开始下载我的任务 我进入后台,10 秒后切换到“aireplan 模式” 我的所有任务都出错了。所以在方法 URLSession:task:didCompleteWithError: 我恢复他们使用 downloadTaskWithResumeData 或者如果我不能(因为有些没有 足够的恢复数据)我正在创建一个没有恢复它的新任务(除非当时网络恢复了)。 然后我把wifi挂了 由于我仍在后台运行,因此当网络恢复时,如果不启动应用程序,我无法触发“恢复”...

我该如何解决这些问题?我错过了什么吗?

【问题讨论】:

我和你一样失望。您提到您正在等待 Apple 对此的答复。你有听过他们的消息吗?分辨率是多少? 与 Apple 进行了很多交流但效果不佳,建议使用应处理这些情况的酌情标志(但不保证及时结果)。这种模式不是我的目标,我并没有过多关注,但我的测试没有成功。如果您已经对此部分进行了测试,那么获取信息仍然很有趣。 【参考方案1】:

由于我仍在后台,所以当网络恢复时,我无法在不启动应用程序的情况下触发“恢复”……


您可以使用“后台抓取”,当应用程序通过抓取启动时,您可以检查网络并恢复下载任务。

【讨论】:

这可能是一种解决方法……现在正在等待 Apple 的答复。 @Gros 你从苹果那里得到了关于这个的答复吗?我也有同样的问题。 最后没有得到有用的答案【参考方案2】:

您应该使用后台配置创建 NSURLSession,然后将您的任务发送到后台恶魔,并在完成后调用您的应用程序。

【讨论】:

【参考方案3】:

实施:

application:handleEventsForBackgroundURLSession:completionHandler:

在应用程序委托中 - 不调用 completionHandler - 导致应用程序在设备在挂起时失去连接后在后台挂起。这样,当网络连接再次可用时,应用程序仍然可以收听可达性通知并重新开始下载。但是,这是一种非常狡猾的方法,可能无法通过 Apple 的应用商店提交指南。此外,当应用程序在前台时连接丢失并且在应用程序暂停时重新连接时,这种方法也没有多大帮助。

最后我做了以下事情:

利用application:handleEventsForBackgroundURLSession:completionHandler: 通知在后台暂停我的下载。 利用间歇性后台获取通知(即application:performFetchWithCompletionHandler:completionHandler)检查连接状态并重新启动任何暂停的下载。 (帽子提示@gugupluto)

这仍然不能提供最佳的下载性能,并且可能会导致用户想知道为什么他们的“后台下载”在重新打开应用程序后还没有完成,但这似乎是我们目前可以从 Apple 获得的最好的期望。

【讨论】:

据我所知,应用程序有一定的时间(大约 30 秒)来调用传递的完成处理程序,如果它不这样做,那么它将被看门狗,除了当被调试即通过Xcode启动时,这可能会让一些开发人员认为忽略完成处理程序是一个有效的解决方法,而实际上不是。 @oscahie 这是有道理的,但这不是我在第四代 iPad 上测试时所看到的。该应用似乎无限期地留在后台并响应网络可达性通知。

以上是关于NSURLSession 后台下载 - 通过网络故障恢复的主要内容,如果未能解决你的问题,请参考以下文章

iOS NSURLSession 实现网络请求-文件下载-上传-后台下载

NSURLSession 后台会话中的 NSURLSessionDownloadTask 给出错误

通过 NSURLSession / NSURLSessionDownloadTask 下载完成时发送本地通知

NSURLSession 后台断点下载

NSURLSession,数据任务转换为下载任务后,后台无法下载

NSURLSession 后台任务:避免重复