NSURLSession 断点下载,需要使用到NSURLSessionDownloadTask任务.
知识点:
1. 暂停下载
[ self.downloadTask supend ];
2. 取消下载
[ self.downloadTask cancel ]; 不可恢复下载
[ self.downloadTask cancelByProducingResumeData:comp ]; 可以恢复下载
3. 恢复下载
[ self.downloadTask resume ];
缺点:
使用NSURLSessionDownloadTask来实现断点下载时出现的问题:
当文件下载一半时,用户直接退出应用程序.当用户再打开应用程序时,文件不会继续下载.
所以一般在开发中:我们不适用NSURLSessionDownloadTask来实现大文件断点下载
代码:
// Created by 朝阳 on 2017/12/18.
// Copyright © 2017年 sunny. All rights reserved.
//
#import "ViewController.h"
@interface ViewController ()
@property (nonatomic,strong) NSURLSessionDownloadTask *downloadTask;
@property (nonatomic,strong) NSData *resumeData;
@property (nonatomic, strong) NSURLSession *session;
@property (weak, nonatomic) IBOutlet UIProgressView *progress;
@end
@implementation ViewController
/*
注意: 使用NSURLSessionDownloadTask来实现断点下载时出现的问题:
当文件下载一半时,用户直接退出应用程序.当用户再打开应用程序时,文件不会继续下载.
所以一般在开发中: 我们不适用NSURLSessionDownloadTask来实现大文件断点下载
*/
// 开始下载
- (IBAction)startDownload:(id)sender
{
//1. 确定请求路径
NSURL *url = [NSURL URLWithString:@"http://flv2.bn.netease.com/videolib3/1604/28/fVobI0704/SD/fVobI0704-mobile.mp4"];
//2. 创建请求
NSURLRequest *request = [NSURLRequest requestWithURL:url];
//3. 创建会话对象
self.session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[NSOperationQueue mainQueue]];
//4. 创建downloadTask
NSURLSessionDownloadTask *downloadTask = [self.session downloadTaskWithRequest:request];
//5. 执行task
[downloadTask resume];
self.downloadTask = downloadTask;
}
// 暂停下载(可以恢复下载)
- (IBAction)supendDownload:(id)sender
{
NSLog(@"+++++++++++++++++++暂停");
[self.downloadTask suspend];
}
// 取消下载
// cancel方法: 不可恢复下载
// cancelByProducingResumeData方法: 可恢复下载
- (IBAction)cancelDownload:(id)sender
{
NSLog(@"+++++++++++++++++++取消");
// [self.downloadTask cancel];
/**
当点击取消后,可以继续恢复下载
@param resumeData 记录下载的信息,下载到什么位置
*/
[self.downloadTask cancelByProducingResumeData:^(NSData * _Nullable resumeData) {
self.resumeData = resumeData;
}];
}
// 恢复下载
- (IBAction)resumeDownload:(id)sender
{
//判断: 当self.resumeData有值的时候(代表是点击取消按钮).需要从新获取下载任务
if(self.resumeData){
self.downloadTask = [self.session downloadTaskWithResumeData:self.resumeData];
}
[self.downloadTask resume];
}
#pragma -mark NSURLSessionDownloadDelegate
/**
写数据
@param session 会话对象
@param downloadTask 下载任务
@param bytesWritten 本次写入的数据大小
@param totalBytesWritten 下载的数据总大小
@param totalBytesExpectedToWrite 文件总大小
*/
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite
{
// 文件的下载进度
NSLog(@"%f",1.0 * totalBytesWritten / totalBytesExpectedToWrite);
self.progress.progress = 1.0 * totalBytesWritten / totalBytesExpectedToWrite;
}
/**
当恢复下载的时候调用该方法
@param fileOffset 从什么地方下载
@param expectedTotalBytes 文件总大小
*/
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didResumeAtOffset:(int64_t)fileOffset expectedTotalBytes:(int64_t)expectedTotalBytes
{
NSLog(@"%s, line = %d", __FUNCTION__, __LINE__);
}
/**
当下载完成的时候调用
@param location 文件的临时存储路径
*/
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location
{
NSLog(@"%@",location);
//1. 拼接cache路径
NSString *fullPath = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:downloadTask.response.suggestedFilename];
//2. 剪切到指定位置
[[NSFileManager defaultManager] moveItemAtURL:location toURL:[NSURL fileURLWithPath:fullPath] error:nil];
NSLog(@"%@",fullPath);
}
/**
请求结束时调用
*/
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error
{
NSLog(@"didCompleteWithError");
}
- (void)dealloc
{
[self.session invalidateAndCancel];
}
@end