美文网首页iOS 常见实践iOS源码解析
iOS后台下载管理工具-XXDownload

iOS后台下载管理工具-XXDownload

作者: 羊子222 | 来源:发表于2017-06-21 00:10 被阅读1446次

    iOS 后台下载管理工具 XXDownload,通过传入一个url地址就开始下载并且是支持后台下载的,底层是用NSURLSessionDownloadTask实现的。以下是这个工具的使用方法。

    一、准备工作

    1、安装
    使用cocopods安装,或者直接把Demo中的XXDownload文件夹拖入到项目中

    pod 'XXDownload',:git => 'https://github.com/XXDownload/XXDownload.git'
    

    2、导入头文件

    #import <XXDownload.h>
    

    3、在appDelegate的这个代理方法中添加如下代码

    - (void)application:(UIApplication *)application handleEventsForBackgroundURLSession:(NSString *)identifier completionHandler:(void (^)())completionHandler {
        
        [[XXDownloadManager sharedManager] addFinishBlock:completionHandler identifier:identifier];
    }
    
    

    4、提供数据库操作类
    如果不提供这个类则下载列表的数据只会存在内存中,当应用退出再启动的时候下载列表是空的。

    ①数据库操作类可以把下载任务列表保存到本地,当应用退出再启动时下载列表才不会丢失。这部分可以自己实现,也可以使用demo中的 XXDownloadDBHelper 这个类,这个类用FMDB来操作数据库,所以需要 pod FMDB。

    demo中的数据库操作类

    [XXDownloadManager sharedManager].dbHelper = [[XXDownloadDBHelper alloc] init];
    

    ②数据库操作类只是对 XXDownloadModel 类操作,不需要操作XXDownloadTask,只有 XXDownloadModel 这些属性需要保存到数据库中去,其他的属性没有必要保存到数据库。

    ③自己实现的话需要遵守XXDownloadDBDelegate这个协议,并实现以下几个方法:

    /**
     获取所有的下载任务
     
     @return 下载任务数组
     */
    - (NSArray<XXDownloadModel *> *)getAllTasks;
    
    /**
     将未入库的下载任务插入到库中去
     
     @param downloadArray 下载数组
     */
    - (void)insertTasks:(NSArray<XXDownloadModel *> *)downloadArray;
    
    /**
     更新下载任务 用 model 里面的所有属性去更新表里面的所有属性
     
     @param taskArray 下载任务数组
     */
    - (void)updateTasks:(NSArray<XXDownloadModel *> *)taskArray;
    
    /**
     删除表中的model记录
     
     @param model 任务
     */
    - (void)deleteTask:(XXDownloadModel *)model;
    
    
    二、任务操作

    1、创建一个下载任务

    XXDownloadTask *task = [XXDownloadTask taskWithId:taskId name:name type:XXDownloadTypeUrl url:url size:0];
    

    2、把这个任务添加到下载队列中
    ① 如果是调用的 insertTask,如果同时下载的任务数大于正在下载的个数,则该任务直接开始下载,如果同时下载的任务数小于正在下载的个数,则先暂停下载数组中的第一个任务,并把被暂停的任务插入等待数组中的第一个位置,然后递归上述过程直到这个新添加的任务开始下载。

    [[XXDownloadManager sharedManager] insertTask:task];
    

    ②如果是调用的 addTask,如果同时下载的任务数大于正在下载的个数,则该任务直接开始下载,如果同时下载的任务数小于正在下载的个数,则该任务直接添加到等待数组。

    [[XXDownloadManager sharedManager] addTask:task];
    

    3、开始任务
    当任务是暂停状态时才调用这个方法,开始这个任务,让这个任务插入等待数组中的第一个位置

    [[XXDownloadManager sharedManager] startTask:task];
    

    4、暂停任务
    当任务是等待状态或者正在下载的状态的时候调用暂停任务的方法,将该任务从等待列表或者正在下载的列表中移除。

    [[XXDownloadManager sharedManager] pauseTask:task];
    

    5、删除任务

     [[XXDownloadManager sharedManager] deleteTask:task];
    
    三、回调

    1、下载进度和下载状态的回调
    ①设置代理对象

    [XXDownloadManager sharedManager].delegate = self;
    

    ②实现代理方法

    /**
     下载状态回调
     
     @param task 下载任务
     @param state 状态
     */
    - (void)downloadTask:(XXDownloadTask *)task stateChanged:(XXDownloadState)state;
    
    /**
     下载进度回调
     
     @param task 下载任务
     @param dSize 已下载大小  单位 MB
     @param tSize 总大小     单位 MB
     @param progress  进度
     @param speed 速度
     */
    - (void)downloadTask:(XXDownloadTask *)task downloadSize:(CGFloat)dSize totalSize:(CGFloat)tSize progress:(CGFloat)progress speed:(CGFloat)speed;
    
    @optional;
    /**
     下载任务的缓存目录
    
     @param task 下载任务
     @return 缓存目录
     */
    - (NSString *)cacheDirectoryWithdownloadTask:(XXDownloadTask *)task;
    /**
     下载任务的文件保存目录
     
     @param task 下载任务
     @return 缓存目录
     */
    - (NSString *)downloadDirectoryWithdownloadTask:(XXDownloadTask *)task;
    
    

    其中主要是下载任务的状态的变化和下载进度的回调。当任务下载完成的时候可以在下载状态的回调中对该任务的文件做相应的操作比如说拷贝和发出下载完成的本地通知等,文件的路径会保存放到 task.savePath这个属性中。

    2、任务配置回调
    ①设置代理对象

    [XXDownloadManager sharedManager].taskSetUpdelegate = self;
    

    ②实现代理方法

    /**
     下载任务将要开始  可以对该任务做最后的配置   
     @param task 将要开始的任务
     @param successBlock 配置成功过后的回调
     @param failBlock 配置失败后的回调
     */
    - (void)downloadTaskWillStart:(XXDownloadTask *)task setUpFinish:(void(^)())successBlock failBlock:(void(^)())failBlock;
    

    任务将要开始的时候可以对这个任务做一些配置,配置完成后可以开始,如果配置失败则该任务不开始。

    四、问题

    应用退到后台的时候,当上一个任务完成的时候,感觉并没有立即开始下一个任务而是等了一段时间才开始的。如果有大神了解这块,麻烦告知一下。

    五、demo及地址

    https://github.com/XXDownload/XXDownload.

    相关文章

      网友评论

      • 61a13fde3f8e:作者你好,我遇到一个问题是,有几个task在执行下载,进入后台后,它会很快走到URLSessionDidFinishEventsForBackgroundURLSession并且app没有继续下载了,而且会不定时的唤醒app走到appdelegate的handleEventsForBackgroundURLSession这个代理中😂
        61a13fde3f8e:@羊子222 必现,用的递归创建task完成一系列的ts片段下载的,但之前看到说是不执行appdelegate的代理block是不会那么快结束的啊:sob:
        羊子222:必现的嘛?是不是资源问题导致的哦?
      • EvenTime:http://www.jianshu.com/p/2d8bc5b4563f 去掉这个键值对就可以了,但是不知道在iOS 10如何,我已经没有低系统了,没法玩了,原来我们一直在改里面的东西,居然只要去掉就可以了........兄弟可以更新下你的库了.
        羊子222:@_xiaoChun 这个去掉了?你之前说的下载数据有问题的bug就没有了?那这个后台下载完了进入前台后没有及时更新UI这个还有嘛?我这里有iOS10的系统,谢谢了!:smile:
      • EvenTime:楼主你好,我想提个小建议.首先这个框架,代码写得不错,案例也比较完善,运行起来比较稳定,初步感觉还是不错的.楼主在末尾说的那个问题我也之前就发现了,总体来说还是挺好的.
        就是保存的路径,楼主能不能加上后缀,比如MP4,dmg等等.虽然我们可以对文件进行操作一次,但是还是不太方便,完全可以在第一次移动的时候就弄好.
        还有个问题,就是后台下载,我们可能很久不去看它,比如过了10分钟后,20分钟后,然后就会出现一种结果,下载进度到达了0.99,已下载文件大小比总大小略小一点,但是下载状态已经显示完成,然后缓存的数据就无法使用.
        我还没试过反复点击下载中的任务,下次试试.
        羊子222:@_xiaoChun 我们的应用我们也是下载的视频文件,因为在网上找不到视频文件的链接地址,所以就找了安装包之类的。我们应用上线运行中也有报这个bug的,就是下载完了,实质下载的文件是不全的或者是有损坏的,就是不是必现的。所以技术支持总是说把文件删了重新下载。你有没有找到好的库哦。
        EvenTime:@羊子222 其实我查看了好几个下载的框架了,在后台下载的场景下,都不是理想状态.昨天晚上我用你的案例添加了5个任务,有2个是这样的情况,当然我换了一份json文件,我还是比较喜欢下载视频文件.还有就是在有些时候从后台进入前台,正在下载的任务没有及时刷新,这个是看概率的,并不是每次回出现.很多下载库有一个通病,就是你频繁切换下载中和暂停的状态,这个是有比较大的几率导致数据损坏的,而且是要在xocde停止状态下,连线状态都是比较爽的看起来.但是用户不可能连接着线,也有的人会反复点击.对此我也很无语.
        羊子222:@_xiaoChun 命名这个可以取一下suggestName重新命一下,也有代理传出去了自己可以定制一下,我们项目里面因为这个后缀不统一,那会儿就没有弄。你说的这个后台下载这个每次都必现啊?

      本文标题:iOS后台下载管理工具-XXDownload

      本文链接:https://www.haomeiwen.com/subject/pidaqxtx.html