NSURLSessionDownloadTask文件下载 和 NSURLConnection 下载的区别:
使用NSURLSessionDownloadTask任务来下载文件,不需要保存到沙盒中,downloadTaskWithRequest:comp 方法会自动将请求的数据,保存到沙盒中.
所以不需要手动将下载的数据写入到沙盒中.
知识点:
1. 使用block块的方式来下载数据无法监听数据的下载进度. 使用代理的方法可以监听数据的下载进度
2. NSURLSessionDownloadTask任务 会自动做沙盒缓存,将数据保存到 tmp 中.
3. location 属性: 数据保存到临时数据沙盒tmp中的路径
[[NSFileManager defaultManager] moveItemAtURL:location toURL:[NSURL fileURLWithPath:fullPath] error:nil];
5. 获得下载文件的 名称及后缀的两种方式:
NSLog(@"%@",response.suggestedFilename);
NSLog(@"%@",url.lastPathComponent);
6. 只要创建NSURLSession对象,在结束时都要释放,否则会造成内存泄漏
- (void)dealloc
{
// 如果session设置代理的话,会有一个强引用.不会被释放.因此最后要释放session对象:调用下面两个方法都行.\
否则会有内存泄漏.
// finishTasksAndInvalidate
[self.session invalidateAndCancel];
}
缺点:
1.如果用户点击暂停之后退出程序,那么需要把恢复下载的数据写一份到沙盒,代码复杂度更
2.如果用户在下载中途未保存恢复下载数据即退出程序,则不具备可操作性
// Created by 朝阳 on 2017/12/18.
// Copyright © 2017年 sunny. All rights reserved.
//
#import "ViewController.h"
@interface ViewController ()
@property (nonatomic,strong) NSURLSession *session;
@end
@implementation ViewController
- (NSURLSession *)session
{
if (!_session) {
_session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[NSOperationQueue mainQueue]];
}
return _session;
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[self delegateDownload];
}
// 使用block块的方式来下载数据
// 优点: 不需要手动将数据做沙盒缓存
// 缺点: 无法监听数据的下载进度
- (void)blockDownload
{
//1. 确定请求的URL路径
NSURL *url = [NSURL URLWithString:@"http://localhost:8080/MJServer/resources/images/minion_01.png"];
//2. 创建请求
NSURLRequest *request = [NSURLRequest requestWithURL:url];
/**
注意: 这个方法 会自动将请求的数据,保存到沙盒中: tmp 临时数据中
4. 创建Task任务
param location 数据保存到临时数据tmp中的路径
param response 响应头 response.suggestedFilename 获取资源图片的名称
param error 错误信息
return downloadTask
*/
NSURLSessionDownloadTask *downloadTask = [self.session downloadTaskWithRequest:request completionHandler:^(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error) {
// 在子线程
//4.1 拼接文件全路径
NSString *fullPath = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:response.suggestedFilename];
//4.2 剪切文件到指定位置
[[NSFileManager defaultManager] moveItemAtURL:location toURL:[NSURL fileURLWithPath:fullPath] error:nil];
NSLog(@"%@",location);
NSLog(@"%@",fullPath);
NSLog(@"%@",response.suggestedFilename);
NSLog(@"%@",url.lastPathComponent);
}];
//5. 执行任务
[downloadTask resume];
}
// 使用代理的方式来下载数据
- (void)delegateDownload
{
//1. 确定请求路径
NSURL *url = [NSURL URLWithString:@"http://localhost:8080/MJServer/resources/images/minion_01.png"];
//2. 创建请求
NSURLRequest *request = [NSURLRequest requestWithURL:url];
//3. 创建会话对象
//4. 创建downloadTask
NSURLSessionDownloadTask *downloadTask = [self.session downloadTaskWithRequest:request];
//5. 执行task
[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);
}
/**
当恢复下载的时候调用该方法
@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
{
// 如果session设置代理的话,会有一个强引用.不会被释放.因此最后要释放session对象:调用下面两个方法都行.\
否则会有内存泄漏.
// finishTasksAndInvalidate
[self.session invalidateAndCancel];
}
@end