iOS的info.plist文件配置
一.使用DataTask下载
#import "ViewController.h"
@interface ViewController ()<NSURLSessionDataDelegate>
/**接受信息*/
@property (nonatomic,strong) NSMutableData *mData;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
//1.url
NSURL *url = [NSURL URLWithString:@"http://b.hiphotos.baidu.com/image/h%3D300/sign=77d1cd475d43fbf2da2ca023807fca1e/9825bc315c6034a8ef5250cec5134954082376c9.jpg"];
//2.request
NSURLRequest *request = [NSURLRequest requestWithURL:url];
//3.NSURLSession
NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession *session = [NSURLSession sessionWithConfiguration:config delegate:self delegateQueue:[NSOperationQueue mainQueue]];
//创建task
NSURLSessionDataTask *task = [session dataTaskWithRequest:request];
//开始下载
[task resume];
}
//接收到服务器响应
-(void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler{
//接收到响应信息
self.mData = [NSMutableData data];
//和urlConnection不同点在于
//接收到响应信息之后 是否需要继续下载 必须自己配置
//告诉服务器继续传递数据 NSURLSessionResponseAllow
completionHandler(NSURLSessionResponseAllow);
}
//接收到服务器返回数据
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data{
//追加信息
[_mData appendData:data];
}
//请求完成
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error{
//解析服务器返回的数据
NSLog(@"%@", [UIImage imageWithData:_mData]);
}
@end
二.使用DownloadTask下载
优势:
1.可以实现一边下载一边保存
2.不受苹果后台设置的时间的限制,可以在程序退到后台后继续session中未完成的task,直到全部完成退出后台
3.在服务器满足苹果API要求的情况下,让断点续传摆脱bytes=%llu-,更简单易用
2.1.NSURLSessionDownloadTask之block下载
//url
NSURL *url = [NSURL URLWithString:@"https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1555431276825&di=f6de13e3bae100df9f2be9b14e305df4&imgtype=0&src=http%3A%2F%2Fuploads.5068.com%2Fallimg%2F1801%2F160I4E61-7.jpg"];
//创建会话对象
NSURLSession *session = [NSURLSession sharedSession];
//创建task
NSURLSessionDownloadTask *task = [session downloadTaskWithURL:url completionHandler:^(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error) {
//获取保存文件的路径
NSString *path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject stringByAppendingPathComponent:@"1.png"];
//将url对应的文件copy到指定的路径
[[NSFileManager defaultManager] moveItemAtURL:location toURL:[NSURL fileURLWithPath:path] error:nil];
}];
//执行task
[task resume];
Block下载方式不适合大文件下载,因为该方法需要等到文件下载完毕了,才会回调completionHandler后面的block参数,然后才可以在这个block参数可以获取location(文件下载缓存的路径)、response(响应)、error(错误信息)。这样的话,对于大文件,我们就无法实时的在下载过程中获取文件的下载进度了。
2.2.NSURLSessionDownloadTask之代理方法下载
#import "ViewController.h"
@interface ViewController ()<NSURLSessionDownloadDelegate>
/**全局化的task*/
@property (nonatomic,strong) NSURLSessionDownloadTask *task;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
}
-(void)viewDidAppear:(BOOL)animated{
[super viewDidAppear:animated];
//url
NSURL *url = [NSURL URLWithString:@"https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1555431276825&di=f6de13e3bae100df9f2be9b14e305df4&imgtype=0&src=http%3A%2F%2Fuploads.5068.com%2Fallimg%2F1801%2F160I4E61-7.jpg"];
//默认的congig
NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
//session
NSURLSession *session = [NSURLSession sessionWithConfiguration:config delegate:self delegateQueue:[NSOperationQueue mainQueue]];
//task
self.task = [session downloadTaskWithURL:url];
//启动下载任务
[_task resume];
}
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
//running 正在下载
//suspend 暂停下载
//complete 下载完成
//cancel 取消下载
if (_task.state == NSURLSessionTaskStateRunning) {
//由开始状态变成暂停
[_task suspend];
}else if(_task.state == NSURLSessionTaskStateSuspended){
//由暂停状态变成开始
[_task resume];
}
}
#pragma mark -------代理方法 ---------
//边下载边存储->磁盘->手机的内存->程序的沙盒里面->
//Documents(文件操作) Library(cache缓存) tmp(临时目录)
//将默认下载的数据从url的path移动(copy,move)到自己的位置
//当执行完毕,这个临时文件就会被立刻销毁
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location{
NSLog(@"%@",location);
//获取保存文件的路径
NSString *path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject stringByAppendingPathComponent:@"1.png"];
NSLog(@"%@",path);
//将url对应的文件copy到指定的路径
[[NSFileManager defaultManager] moveItemAtURL:location toURL:[NSURL fileURLWithPath:path] error:nil];
NSLog(@"下载完成");
}
//获取每次下载的长度
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite{
CGFloat progress = totalBytesWritten*1.0/totalBytesExpectedToWrite;
NSLog(@"%f",progress);
}
//下载完成,成功出错都会来到这里
-(void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error{
NSLog(@"%@",error.userInfo);
}
@end
代理方法
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location
location:默认下载的文件存放的位置
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite
session:当前会话
downloadTask:当前会话任务
bytesWritten:本次写入数据大小
totalBytesWritten:已经写入数据大小 totalBytesExpectedToWrite:要下载的文件总大小
-(void)URLSession:(NSURLSession *)session downloadTask:(nonnull NSURLSessionDownloadTask *)downloadTask didResumeAtOffset:(int64_t)fileOffset expectedTotalBytes:(int64_t)expectedTotalBytes
恢复下载时调用的代理方法
-(void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error
下载完成时调用的代理方法
利用DataTask和NSFileHandle实现边下载边保存
#import "ViewController.h"
@interface ViewController ()<NSURLSessionDataDelegate>
/**文件句柄*/
@property (nonatomic,strong) NSFileHandle *fileHandle;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
//url
NSURL *url = [NSURL URLWithString:@"http://b.hiphotos.baidu.com/image/h%3D300/sign=77d1cd475d43fbf2da2ca023807fca1e/9825bc315c6034a8ef5250cec5134954082376c9.jpg"];
//session
NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[NSOperationQueue mainQueue]];
//dataTask
NSURLSessionDataTask *task = [session dataTaskWithURL:url];
//启动任务
[task resume];
}
#pragma mark -------代理方法 ---------
-(void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler{
//为下载做好准备
//1.获取文件路径
//cache tmp
NSString *filePath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).lastObject stringByAppendingPathComponent:@"2.png"];
//2.创建文件 用于接受数据
[[NSFileManager defaultManager] createFileAtPath:filePath contents:nil attributes:nil];
//3.以写的方式创建文件句柄 防止上一次的内容被这一次的内容覆盖
self.fileHandle = [NSFileHandle fileHandleForWritingAtPath:filePath];
//接受响应后是否下载
completionHandler(NSURLSessionResponseAllow);
}
-(void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data{
//接受下载的数据
[_fileHandle writeData:data];
}
-(void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error{
//对结果进行处理
[_fileHandle closeFile];
}
@end
NSOutputStream-保存网络资源到本地
参考文章:https://www.cnblogs.com/hbf369/p/3581986.html
2.3.NSURLSessionDownloadTask之后台下载
步骤:
1.创建request
2.配置允许后台任务的session
3.创建downloadTask
4.服从NSURLSessionDownloadDelegate
5.AppDelegate 监听handleEventsForBackgroundURLSession将handle传递给下载类
6.URLSessionDidFinishEventsForBackgroundURLSession后台下载执行这个方法
7.didFinishDownloadingToURL将临时文件保存到对应位置
//AppDelegate关联session,传递block
-(void)application:(UIApplication *)application handleEventsForBackgroundURLSession:(NSString *)identifier completionHandler:(void (^)(void))completionHandler{
//1.将前台的session和后台的session做一个关联
//找到正常接收代理的对象
ViewController *vc = (ViewController *)self.window.rootViewController;
NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:@"config"] delegate:vc delegateQueue:[NSOperationQueue mainQueue]];
//将completionHandler传递给执行的对象,让其知道我的下载状态
vc.completeHandleBlock = completionHandler;
}
//执行者监听后台是否下载完毕
-(void)URLSessionDidFinishEventsForBackgroundURLSession:(NSURLSession *)session{
NSLog(@"后台任务下载完毕");
self.completeHandleBlock();
}
参考文章:https://www.jianshu.com/p/1211cf99dfc3
2.4.NSURLSessionDownloadTask代理方法实现断点续传下载
参考文章:http://www.cnblogs.com/goodboy-heyang/p/5195806.html
demo链接
链接:https://pan.baidu.com/s/1Yfa9q9EiWd904LOeQ6z8cQ 密码:tfn8
链接:https://pan.baidu.com/s/1BqMiH0Cza88eGBU1GX4d-g 密码:6ipc
链接:https://pan.baidu.com/s/18t4pCZiOkBdyxdzaoilIYg 密码:pg5e
链接:https://pan.baidu.com/s/18uXCNmU50VTS8B6OjnYOFA 密码:fad4
网友评论