文档章节

AFNetWorking 实现文件的下载 断点续传

w_sn
 w_sn
发布于 2016/11/28 14:06
字数 844
阅读 1.7K
收藏 11

「深度学习福利」大神带你进阶工程师,立即查看>>>

最近用到了下载,网上也搜寻过下载方面的东西,没有找到太合适的关于AFNetWorking 3.x方面的断点续传的介绍或者demo,于是自己写吧。 AFURLSessionManager这个封装了上传、下载方面的相关内容,仔细阅读不难发现,这个就是对 NSURLSession 、NSURLSessionTask 进行的封装,下载、上传这些操作用到的就是NSURLSessionTask相关子类。 先说说第一种方式,就是最简单的下载,用到的方法显而易见

/**
  第一种方式
*/
//方法包含了下载所需的 参数 回调 很全面, 这里返回一个NSURLSessionDownloadTask对象,用于调用系统的方法: resume开始、继续下载,suspend暂停下载,cancel取消下载
- (NSURLSessionDownloadTask *)downloadTaskWithRequest:(NSURLRequest *)request
                                             progress:(nullable void (^)(NSProgress *downloadProgress))downloadProgressBlock
                                          destination:(nullable NSURL * (^)(NSURL *targetPath, NSURLResponse *response))destination
                                    completionHandler:(nullable void (^)(NSURLResponse *response, NSURL * _Nullable filePath, NSError * _Nullable error))completionHandler;

/**
  第二种方式 
    可以实现一种不一样的断点续传 我个人感觉这种方式怪怪的 而且似乎不能做到关闭app后恢复断点续传,虽然可以保存之前下载的数据,但是下次的请求体就不存在了。
*/
//首先用第一种方法进行开始下载 然后后续暂停操作
//实现断点的关键地方 用这个方法进行取消操作 可以得到resumeData
- (void)cancelByProducingResumeData:(void (^)(NSData * _Nullable resumeData))completionHandler;
//然后调用的方法同系统方法

/*系统方法 解释  Creates a download task with the resume data.  If the download cannot be successfully resumed, URLSession:task:didCompleteWithError: will be called. */
- (NSURLSessionDownloadTask *)downloadTaskWithResumeData:(NSData *)resumeData;

/*AFN方法 继续进行下载*/
- (NSURLSessionDownloadTask *)downloadTaskWithResumeData:(NSData *)resumeData
                                                progress:(nullable void (^)(NSProgress *downloadProgress))downloadProgressBlock
                                             destination:(nullable NSURL * (^)(NSURL *targetPath, NSURLResponse *response))destination
                                       completionHandler:(nullable void (^)(NSURLResponse *response, NSURL * _Nullable filePath, NSError * _Nullable error))completionHandler;

//上面这种方法 按照解释就是不能正常暂停,采用的一种特殊手段暂停下载,然后进行恢复下载,理论上说就是一种平常的下载,为了处理比较特殊的情况。至于更好的用法,我暂时还没有发现。

/**
    第三种方式 本文要写的重点啦 这个方法其实就是代替了系统提供的代理方法进行下载各方面的操作 详情写在下面
*/

//获取文件大小
//文件大小
- (unsigned long long)fileSizeForPath:(NSString *)path {
    unsigned long long fileSize = 0;
    NSFileManager *fileManager = [NSFileManager defaultManager];
    if ([fileManager fileExistsAtPath:path]) {
        NSError * error = nil;
        NSDictionary * fileDict = [fileManager attributesOfItemAtPath:path error:&error];
        if (!error && fileDict) {
            fileSize =[fileDict fileSize];
        }
    }
    return fileSize;
}
//创建下载请求管理对象
    AFURLSessionManager * manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
//创建流
   NSOutputStream *outputStream = [[NSOutputStream alloc] initWithURL:[NSURL fileURLWithPath:@"文件路径"] append:YES];
//请求体
    NSMutableURLRequest * request = [[NSMutableURLRequest alloc] initWithURL:[[NSURL alloc] initWithString:info.url]];
    unsigned long long cacheFileSize = 0;
    cacheFileSize = [self fileSizeForPath:@"文件路径"];
    if (cacheFileSize) {
        NSString *range = [NSString stringWithFormat:@"bytes=%lld-", cacheFileSize];
        [request setValue:range forHTTPHeaderField:@"Range"];
    }

//下载对象
    NSURLSessionDataTask * task = [manager dataTaskWithRequest:request completionHandler:nil];

//下载接受数据
    [manager setDataTaskDidReceiveResponseBlock:^NSURLSessionResponseDisposition(NSURLSession * _Nonnull session, NSURLSessionDataTask * _Nonnull dataTask, NSURLResponse * _Nonnull response) {
        //下载文件的总大小
        response.expectedContentLength + cacheFileSize
        //打开流
        [outputStream open];
        return NSURLSessionResponseAllow;
    }];
    //写入数据
    [manager setDataTaskDidReceiveDataBlock:^(NSURLSession * _Nonnull session, NSURLSessionDataTask * _Nonnull dataTask, NSData * _Nonnull data) {
        
        NSInteger result = [outputStream write:data.bytes maxLength:data.length];
        if (result == -1) {
            //错误
            outputStream.streamError;
            [task cancel];
        } else {
            //正确操作
        }
    }];
    //下载完成
    [manager setTaskDidCompleteBlock:^(NSURLSession * _Nonnull session, NSURLSessionTask * _Nonnull task, NSError * _Nullable error) {
        [outputStream close];
        outputStream = nil;
        task = nil;
        if (error) {
        }
    }];

//⚠️  上面的方法其实就是相当于系统的代理方法,具体的可以去查看 AFURLSessionManager.h 里面有详细的说明 demo待我整理整理 github奉上。
w_sn

w_sn

粉丝 7
博文 21
码字总数 12750
作品 1
天津
iOS工程师
私信 提问
加载中
请先登录后再评论。
用vertx实现高吞吐量的站点计数器

工具:vertx,redis,mongodb,log4j 源代码地址:https://github.com/jianglibo/visitrank 先看架构图: 如果你不熟悉vertx,请先google一下。我这里将vertx当作一个容器,上面所有的圆圈要...

jianglibo
2014/04/03
4.2K
3
SQLServer实现split分割字符串到列

网上已有人实现sqlserver的split函数可将字符串分割成行,但是我们习惯了split返回数组或者列表,因此这里对其做一些改动,最终实现也许不尽如意,但是也能解决一些问题。 先贴上某大牛写的s...

cwalet
2014/05/21
9.6K
0
我的架构演化笔记 功能1: 基本的用户注册

“咚咚”,一阵急促的敲门声, 我从睡梦中惊醒,我靠,这才几点,谁这么早, 开门一看,原来我的小表弟放暑假了,来南京玩,顺便说跟我后面学习一个网站是怎么做出来的。 于是有了下面的一段...

强子哥哥
2014/05/31
976
3
CDH5: 使用parcels配置lzo

一、Parcel 部署步骤 1 下载: 首先需要下载 Parcel。下载完成后,Parcel 将驻留在 Cloudera Manager 主机的本地目录中。 2 分配: Parcel 下载后,将分配到群集中的所有主机上并解压缩。 3 激...

cloud-coder
2014/07/01
6.8K
1
beego API开发以及自动化文档

beego API开发以及自动化文档 beego1.3版本已经在上个星期发布了,但是还是有很多人不了解如何来进行开发,也是在一步一步的测试中开发,期间QQ群里面很多人都问我如何开发,我的业余时间实在...

astaxie
2014/06/25
2.7W
22

没有更多内容

加载失败,请刷新页面

加载更多

PPDet:减少Anchor-free目标检测中的标签噪声,小目标检测提升明显

本文转载自AI算法修炼营。 这篇文章收录于BMVC2020,主要的思想是减少anchor-free目标检测中的label噪声,在COCO小目标检测上表现SOTA!性能优于FreeAnchor、CenterNet和FCOS等网络。整体思路...

我爱计算机视觉
昨天
0
0
BIO、NIO、AIO 区别和应用场景

点击上方“ java1234 ”,选择“标星公众号” 优质文章,第一时间送达 66套java从入门到精通实战课程分享...

小锋2
今天
0
0
ContentProvider(查询 插入 修改 删除 )

注意 本篇实在sqlite的基础上编写的所以建议首先了解sqlite 首先建立两个模块 ContentProvider ContentResolver ContentProvider 里面需要建立表和建立连接 所以在这里需要建立DBHelp类 DBHe...

osc_6ttvlt1w
9分钟前
0
0
用这个网站一查,才知道自己被卖了

还记得上个月好多大佬的Twitter账号被盗用于网络诈骗的事件吗。 7月15日,美国前总统奥巴马、“股神”巴菲特、特斯拉CEO马斯克、微软创始人比尔·盖茨等人的账户连续“被登录”,用来向大众诈...

猿大白
今天
0
0
牛客多校第9场E Groundhog Chasing Death

开始以为是什么高深的数论题,后来 重新 推了一下,得到了个这么个式子。 ∏ i = a b ∏ j = c d ( p 1 m i n ( a 1 [ 1 ] i , a 2 [ 1 ] j ) p 2 m i n ( a 1 [ 2 ] i , a 2 [ 2 ] j ) . . ...

osc_wdq5dwoy
11分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部