使用NSURLSessionDownloadTask实现大文件下载-监听下载进度
阅读原文时间:2023年07月11日阅读:4

- 5.1 涉及知识点

(1)创建NSURLSession并设置代理,通过NSURLSessionDownloadTask并以代理的方式来完成大文件的下载

//1.创建NSURLSession,设置代理  
self.session = \[NSURLSession sessionWithConfiguration:\[NSURLSessionConfiguration defaultSessionConfiguration\] delegate:self delegateQueue:\[NSOperationQueue mainQueue\]\];

//2.创建task  
NSURL \*url = \[NSURL URLWithString:@"http://120.25.226.186:32812/resources/videos/minion\_01.mp4"\];  
self.downloadTask = \[self.session downloadTaskWithURL:url\];

//3.执行task  
\[self.downloadTask resume\];

(2)常用代理方法的说明

/*
1.当接收到下载数据的时候调用,可以在该方法中监听文件下载的进度
该方法会被调用多次
totalBytesWritten:已经写入到文件中的数据大小
totalBytesExpectedToWrite:目前文件的总大小
bytesWritten:本次下载的文件数据大小
*/
-(void)URLSession:(nonnull NSURLSession *)session downloadTask:(nonnull NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite
/*
2.恢复下载的时候调用该方法
fileOffset:恢复之后,要从文件的什么地方开发下载
expectedTotalBytes:该文件数据的总大小
*/
-(void)URLSession:(nonnull NSURLSession *)session downloadTask:(nonnull NSURLSessionDownloadTask *)downloadTask didResumeAtOffset:(int64_t)fileOffset expectedTotalBytes:(int64_t)expectedTotalBytes
/*
3.下载完成之后调用该方法
*/
-(void)URLSession:(nonnull NSURLSession *)session downloadTask:(nonnull NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(nonnull NSURL *)location
/*
4.请求完成之后调用
如果请求失败,那么error有值
*/
-(void)URLSession:(nonnull NSURLSession *)session task:(nonnull NSURLSessionTask *)task didCompleteWithError:(nullable NSError *)error

(3)实现断点下载相关代码

//如果任务,取消了那么以后就不能恢复了  
//    \[self.downloadTask cancel\];

//如果采取这种方式来取消任务,那么该方法会通过resumeData保存当前文件的下载信息  
//只要有了这份信息,以后就可以通过这些信息来恢复下载  
\[self.downloadTask cancelByProducingResumeData:^(NSData \* \_\_nullable resumeData) {  
    self.resumeData = resumeData;  
}\];

-----------  
//继续下载  
//首先通过之前保存的resumeData信息,创建一个下载任务  
self.downloadTask = \[self.session downloadTaskWithResumeData:self.resumeData\];

 \[self.downloadTask resume\];

(4)计算当前下载进度

//获取文件下载进度
self.progress.progress = 1.0 * totalBytesWritten/totalBytesExpectedToWrite;

(5)局限性

    01 如果用户点击暂停之后退出程序,那么需要把恢复下载的数据写一份到沙盒,代码复杂度更

    02 如果用户在下载中途未保存恢复下载数据即退出程序,则不具备可操作性