随着苹果提供API的不断完善,实现下载管理的方法也发生了一些变化。从使用更方便的第三方库,到完全可以用自带API实现毫无压力。且将各种方法记录于此,权当备查。
首先定义一下下载管理的范围:
接下来,从最早采用的实现方法说起。
NSOperation
的自定义类; NSURLSessionDownloadTask
)作为其中的一个属性;
这里附上苹果开发者论坛中,一位开发者与苹果开发者的关于 NSURLSession
的问答(2015年7月)。
我需要在我的app中上传200张图片,
1.我该使用 NSURLSessionUploadTask
还是其他什么类?
答: NSURLSessionUploadTask
.
2.为了让这些upload保持在background,我该做些什么?
答:把所有的upload扔进一个 NSURLSession
的background session中。
3.当app没有在运行的时候,我该做些什么?(没有明确回答)
4.针对以上3点,我该在 NSURLSession
外面包一层 NSOperation
以便于使用 NSOperationQueue
,还是说,iOS会有它自己的内部queue来正确处理 NSURLSession
对象们?
答:这个很难说。一般来说,我是 NSOperation
的死忠粉,但由于background session和app生命周期的交互方式,用 NSOperation
来解决 NSURLSession
的background session的问题却有些棘手。
具体来说,通常的流程是这样的:
1.你的app开始一堆后台传输;
2.用户把它移到后台;
3.系统暂停了你的app;
4.传输在后台继续运行;
5.系统终止了你的app;
6.传输继续在后台运行;
7.传输结束;
8.系统重新启动你的app。
如果你使用 NSOperation
来追踪每个传输,当你在第8步重新启动app时,就需要重新创建那一堆的operation。当然,在第8步是需要重新创建 一些东西
,只是重新创建 NSOperation
要比重新创建其他不那么复杂的对象棘手些。
5.你的意思是说,如果我一次性把200个 NSURLSessionUploadTask
的实例添加到同一个background session配置的 NSURLSession
中,iOS会把它们都正确处理好?
答:是的。 NSURLSession
后台下载系统会很乐意处理几百个请求的。它在内部将它们串联起来,所以在任何时候只有少量的请求是在执行中。
6.如果是的话,对于task的数量是否有所限制?
答:没有硬性规定,但我通常建议不要做的太过分。在我看来,几百个请求是可以接受的,几千个请求就有点勉强,上万的请求就有点2。。我通常建议,如果你不得不处理上千个单独的item,你可以把它们打包起来,然后进行一个可恢复的传输。然而,有一些问题:
NSURLSession
的background session自动处理下载的断点续传。但对于上传并非如此。如果你需要上传的断点续传,你就得涉及到每次的连接数据(这里原文用的是”tears”,不太理解。。)。考虑到这个原因,把上传文件打包成合理大小的整块文件就很有必要,这样上传就会产生一打的进度,即使有可能连接失败,也好过你的app重新恢复上传。
另外,对于如何知道当前并行的下载数, MZDownloadManager
的作者也在这个issue下给出了 答案
。简而言之,就是通过筛选存储着model的array,得到状态为“下载中”的model的数量。