NSURLSessionDataTask下载文件
1.创建NSURLSessionDataTask和NSURLSession
-(NSURLSession *)session
{
if (_session == nil) {
_session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[NSOperationQueue mainQueue]];
}
return _session;
}
- (NSURLSessionDataTask *)dataTask
{
if (_dataTask == nil) {
// 01 确定资源路径
NSURL *url = [NSURL URLWithString:@"url"];
// 02 创建请求对象
NSMutableURLRequest *request = [[NSMutableURLRequest alloc]initWithURL:url];
//+ 设置请求头信息-Range(下载数据范围)
/*
Range:
bytes=0-100
bytes=-100 文件开始-100
bytes=400-1000
bytes=400- 400个字节的位置开始一直到文件的结尾
*/
NSString *header = [NSString stringWithFormat:@"bytes=%zd-",self.currentSize];
[request setValue:header forHTTPHeaderField:@"Range"];
_dataTask = [self.session dataTaskWithRequest:request];
}
return _dataTask;
}
2.NSURLSessionDataDelegate
//01 接收到响应的时候调用,每发送一次请求就会调用一次该方法
-(void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler
{
//得到本次请求的文件大小,文件的总大小 = 本次请求数据的大小 + 已经下载的文件大小
self.totalSize = response.expectedContentLength + self.currentSize;
//把总文件的大小保存起来(沙盒)
NSData *sizeData = [[NSString stringWithFormat:@"%zd",self.totalSize] dataUsingEncoding:NSUTF8StringEncoding];
[sizeData writeToFile:KSizefullPath atomically:YES];
//判断是否是第一次发送请求下载文件(创建空文件)
if (self.currentSize == 0) {
[[NSFileManager defaultManager] createFileAtPath:KfullPath contents:nil attributes:nil];
}
//创建文件句柄指针指向该文件,默认指向文件开头
self.handle = [NSFileHandle fileHandleForWritingAtPath:KfullPath];
//移动文件句柄指针指向文件的末尾
[self.handle seekToEndOfFile];
completionHandler(NSURLSessionResponseAllow);
}
//02 接收服务器返回的数据 (可能调用多次)
-(void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data
{
//句柄写入数据
[self.handle writeData:data];
//计算进度
self.currentSize +=data.length;
self.progressView.progress = 1.0 *self.currentSize / self.totalSize;
}
//03 请求完成或者失败
-(void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error
{
// 关闭句柄指针
[self.handle closeFile];
}
3.初始化总文件大小,和当前文件大小
-(void)viewDidLoad
{
[super viewDidLoad];
//拿到之前已经下载的文件数据大小 self.currentSize = 沙盒中文件的大小
//01 得到沙盒中已经下载的文件的属性
NSDictionary *fileInfo = [[NSFileManager defaultManager] attributesOfItemAtPath:KfullPath error:nil];
self.currentSize = [fileInfo fileSize]; //得到沙盒中已经下载文件的总大小
//处理进度信息 = 已经下载大小/文件的总大小
//尝试读取沙盒中文件的信息 (文件的总大小)
NSData *sizeData = [NSData dataWithContentsOfFile:KSizefullPath];
self.totalSize = [[[NSString alloc]initWithData:sizeData encoding:NSUTF8StringEncoding] integerValue];
if (self.totalSize !=0) {
self.progressView.progress = 1.0 * self.currentSize /self.totalSize;
}
}