转载

Some methods for DownloadManager

随着苹果提供API的不断完善,实现下载管理的方法也发生了一些变化。从使用更方便的第三方库,到完全可以用自带API实现毫无压力。且将各种方法记录于此,权当备查。

首先定义一下下载管理的范围:

  • 可以同时下载多个文件;
  • 对于单个文件而已,可以下载/暂定/恢复下载/取消下载/显示下载进度;
  • 可以控制同时下载的最大数量。

接下来,从最早采用的实现方法说起。

  1. NSOperationQueue
  • 创建继承自 NSOperation 的自定义类;
  • 将下载需要的网络请求(如 NSURLSessionDownloadTask )作为其中的一个属性;
  1. dispatch_queue_create()
  2. NSURLSession

核心:All the other APIs -> model -> UI

这里附上苹果开发者论坛中,一位开发者与苹果开发者的关于 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的数量。

Ref:

  • https://forums.developer.apple.com/thread/10239
原文  http://www.calios.gq/2017/01/10/下载管理的一些实现方法/
正文到此结束
Loading...