URLSession,这个类比之前的URLConnection下载数据或者文件,特别是大文件,App的内存和性能提升很多,不会急剧暴增。URLSession的构造方法//单例@property (class, readonly, strong) NSURLSession *sharedSession;//便利构造器+ (NSURLSession *)sessionWithConfiguration:(NSURLSessionConfiguration *)configuration;+ (NSURLSession *)sessionWithConfiguration:(NSURLSessionConfiguration *)configuration delegate:(nullable id <NSURLSessionDelegate>)delegate delegateQueue:(nullable NSOperationQueue *)queue;
接下来的一句话非常重要!!
URLSession所有的网络都是Session发起的。而且所有的任务默认是挂起的,需要调用resume。
先记住这句话,等下会说到。
xxxxxxxxxxself.session = [NSURLSession sharedSession];[[self.session dataTaskWithURL:url completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {}] resume];
delegate,就是你只能用Block回调。
这是因为单例构造的Session是系统全局的。设置delegate会出现你意想不到的事情,比A-App和B-App,两个App同时对单例设置了delegate,delegate是一对一映射,那么可能A-App的数据可能会返还给B-App。xxxxxxxxxx[[[NSURLSession sharedSession] downloadTaskWithURL:url completionHandler:^(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error) {NSLog(@"%@",location);}] resume];
Session的下载文件会暂存到沙盒路径的tmp里面,所以如果下载完成我们不主动去写入别的Path,那么文件很可能就消失了,系统会自动回收这块区域。
xxxxxxxxxxNSURLSessionConfiguration * config = [NSURLSessionConfiguration defaultSessionConfiguration];self.session = [NSURLSession sessionWithConfiguration:config delegate:self delegateQueue:nil];
delegateQueue可以设置nil,默认就是异步队列Session对delegate是强引用,要手动Cancle或者Finish。x-(void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location{NSLog(@"完成 %@",location);//完成任务,[self.session finishTasksAndInvalidate];//置空Sessionself.session = nil;}-(void)viewWillDisappear:(BOOL)animated{[super viewWillDisappear:animated];//取消会话[self.session invalidateAndCancel];self.session = nil;}
不然dealloc不会调用的。
xxxxxxxxxx- (IBAction)pause:(id)sender {[self.downloadTask cancelByProducingResumeData:^(NSData * _Nullable resumeData) {//resumeData : 已下载的数据self.resumeData = resumeData;//释放下载任务self.downloadTask = nil;}];}- (IBAction)resume:(id)sender {//没有续传任务if (self.resumeData == nil) {return;}//续传任务self.downloadTask = [self.session downloadTaskWithResumeData:self.resumeData];//清空续传数据self.resumeData = nil;//所有的任务都是默认挂起的!![self.downloadTask resume];}