iOS-AFNetworking实现断点续传功能

上一节说到利用系统原生的方法实现断点续传功能,这次我们说下当下最时尚的第三方网络请求库AFNetworking,利用AFNet实现断点续传。其实原理是和NSURLSessionDataTask一样的。因为我们都知道AFNet在3.0之后是封装的NSURLSession,想知道AFNet3.0和2.0的区别的所以在方法实现上面几本一样。至于AFNet怎么利用CocoaPod获取请移步到这里

方法实现

1.声明以下属性变量

@property (nonatomic , strong) AFURLSessionManager *manager;
@property (nonatomic , strong) NSURLSessionDataTask *downloadTask;
@property (nonatomic , assign) NSInteger currentLength;
@property (nonatomic , assign) NSInteger totalLength;
@property (nonatomic , strong) NSFileHandle *fileHandle;

2.懒加载manager和downloadTask

创建会话管理者

- (AFURLSessionManager *)manager {
    if (!_manager) {
        NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];

        _manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration];
    }
    return _manager;
}

创建下载任务

- (NSURLSessionDataTask *)downloadTask {
    if (!_downloadTask) {
        // 1.创建下载URL
        NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/resources/videos/minion_01.mp4"];

        // 2.创建request请求
        NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];

        // 设置HTTP请求头中的Range
        NSString *range = [NSString stringWithFormat:@"bytes=%zd-", self.currentLength];
        [request setValue:range forHTTPHeaderField:@"Range"];

        __weak typeof(self) weakSelf = self;

        _downloadTask = [self.manager dataTaskWithRequest:request completionHandler:^(NSURLResponse * _Nonnull response, id  _Nullable responseObject, NSError * _Nullable error) {

            // 下载完成回调block
            NSLog(@"完成");

            // 清空长度
            weakSelf.currentLength = 0;
            weakSelf.totalLength = 0;

            // 关闭fileHandle
            [weakSelf.fileHandle closeFile];
            weakSelf.fileHandle = nil;

        }];

        [self.manager setDataTaskDidReceiveResponseBlock:^NSURLSessionResponseDisposition(NSURLSession * _Nonnull session, NSURLSessionDataTask * _Nonnull dataTask, NSURLResponse * _Nonnull response) {
            NSLog(@"启动任务");
            // 每次唤醒task的时候会回调这个block

            // 获得下载文件的总长度:请求下载的文件长度 + 当前已经下载的文件长度
            weakSelf.totalLength = response.expectedContentLength + self.currentLength;

            // 沙盒文件路径
            NSString *path = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:@"xxxxx"];

            //NSLog(@"File downloaded to: %@",path);

            // 创建一个空的文件到沙盒中
            NSFileManager *manager = [NSFileManager defaultManager];

            if (![manager fileExistsAtPath:path]) {
                // 如果没有下载文件的话,就创建一个文件。如果有下载文件的话,则不用重新创建(不然会覆盖掉之前的文件)
                [manager createFileAtPath:path contents:nil attributes:nil];
            }

            // 创建文件句柄
            weakSelf.fileHandle = [NSFileHandle fileHandleForWritingAtPath:path];

            // 允许处理服务器的响应,才会继续接收服务器返回的数据
            return NSURLSessionResponseAllow;
        }];

        [self.manager setDataTaskDidReceiveDataBlock:^(NSURLSession * _Nonnull session, NSURLSessionDataTask * _Nonnull dataTask, NSData * _Nonnull data) {
            //NSLog(@"setDataTaskDidReceiveDataBlock");
            // 一直回调,直到下载完成

            // 指定数据的写入位置 -- 文件内容的最后面
            [weakSelf.fileHandle seekToEndOfFile];

            // 向沙盒写入数据
            [weakSelf.fileHandle writeData:data];

            // 拼接文件总长度
            weakSelf.currentLength += data.length;

            // 获取主线程,不然无法正确显示进度。
            NSOperationQueue* mainQueue = [NSOperationQueue mainQueue];
            [mainQueue addOperationWithBlock:^{
                // 下载进度
                NSLog(@"当前下载进度:%.2f%%",100.0 * weakSelf.currentLength / weakSelf.totalLength);
            }];
        }];
    }
    return _downloadTask;
}

启动任务

[self.downloadTask resume];

暂停任务

   [self.downloadTask suspend];
   self.downloadTask = nil;

到这里AFNetworking断点续传就完成了,至于多任务下载原理一样的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值