演示效果如下:
利用NSURLSession实现断点下载
1.属性
@interface ViewController ()/** 下载任务 */@property (nonatomic,strong) NSURLSessionDownloadTask *task;/** 上次的下载信息 */@property (nonatomic,strong) NSData *resumeData;/** session */@property (nonatomic,strong) NSURLSession *session;@end
2.初始化属性
- (NSURLSession *)session { if (!_session) { _session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[[NSOperationQueue alloc] init]]; } return _session;}- (NSData *)resumeData { //第一次访问resumeData加载沙盒中的resumeData if (!_resumeData) { NSString *caches = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject]; NSString *file = [caches stringByAppendingPathComponent:@"data"]; _resumeData = [NSData dataWithContentsOfFile:file]; } return _resumeData;}
3.实现点击事件
/** * 开始下载 */- (IBAction)start:(id)sender { //获得下载任务 self.task = [self.session downloadTaskWithURL:[NSURL URLWithString:@"http://120.25.226.186:32812/resources/videos/minion_02.mp4"]]; //启动任务 [self.task resume];}/** * 暂停下载 */- (IBAction)pause:(id)sender { //一旦这个task被取消了,就无法再恢复 //data里面存储着上次的下载信息 [self.task cancelByProducingResumeData:^(NSData * _Nullable resumeData) { self.resumeData = resumeData; //可以将resumeData放到沙盒中 NSString *caches = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject]; NSString *file = [caches stringByAppendingPathComponent:@"data"]; [resumeData writeToFile:file atomically:YES]; }];}/** * 继续下载 */- (IBAction)goOn:(id)sender { self.task = [self.session downloadTaskWithResumeData:self.resumeData]; [self.task resume];}
4.实现代理方法
#pragma mark -- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didResumeAtOffset:(int64_t)fileOffset expectedTotalBytes:(int64_t)expectedTotalBytes { NSLog(@"%s",__func__);}/** * 每当写入数据到临时文件中时,就会调用一次 * totalBytesExpectedToWrite:总大小 * totalBytesWritten:已经写入的大小 * bytesWritten 这次写入大小 */- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite { NSLog(@"%s",__func__); NSLog(@"------%f",1.0*totalBytesWritten/totalBytesExpectedToWrite);}/** * 下载完毕就会调用一次这个方法 */- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location { NSLog(@"%s",__func__); //文件将来存放的真实路径 NSString *file = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:downloadTask.response.suggestedFilename]; //剪切location的临时文件到真实路径 NSFileManager *manager = [NSFileManager defaultManager]; [manager moveItemAtURL:location toURL:[NSURL fileURLWithPath:file] error:nil];}- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error { NSLog(@"%s",__func__);
//保存恢复数据
self.resumeData = error.userInfo[NSURLSessionDownloadTaskResumeData];
}
怎么实现的断点下载?
resumeData里面保存了上次下载的信息
/**
* 请求这个路径
* 设置请求头
* Range: 0-100
* [[NSMutableURLRequest requestWithURL:nil] setValue:@"0-1024" forHTTPHeaderField:@"Range"];
* 通过设置Range这个请求头可以控制下载哪一部分的信息
*/
这些在resumeData都帮你做好了