1.根据URL创建Session,并设置代理:
要跟进下载进度,不能使用全局 session
这里使用的是NSURLSessionDownloadDelegate代理方法
NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:nil];
2.接下来根据URL、创建的session创建下载任务:
self.downloadTask = [session downloadTaskWithURL:url];
ps:通过下面这种方法创建下载任务时,NSURLSessionDownloadDelegate的代理方法将不会不执行:
self.downloadTask =[session downloadTaskWithURL:url completionHandler:^(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error) {
}];
3.切记,所有任务默认都是挂起的,需要手动resume:
[self.downloadTask resume];
4.实现代理方法:
4.1.下载完成,必须实现
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location{
//下载完成后回调. location 就是文件下载之后保存的路径
}
4.1.1 关于location的几个常见属性可以对比Log信息来看
NSLog(@"location:---->%@",location);
NSLog(@"location.path:---->%@",location.path);
NSLog(@"location.absoluteString:---->%@",location.absoluteString);
NSLog(@"location.absoluteURL:---->%@",location.absoluteURL);
4.1.2 Log信息:
location:---->file:///Users/shenyj/Library/Developer/CoreSimulator/Devices/1A092623-6789-42C4-8EB0-DF1777CBE7A5/data/Containers/Data/Application/42E3253A-0D59-42B5-8FF0-ED4C39385278/tmp/CFNetworkDownload_nnzbjb.tmp
location.path:---->/Users/shenyj/Library/Developer/CoreSimulator/Devices/1A092623-6789-42C4-8EB0-DF1777CBE7A5/data/Containers/Data/Application/42E3253A-0D59-42B5-8FF0-ED4C39385278/tmp/CFNetworkDownload_nnzbjb.tmp
location.absoluteString:---->file:///Users/shenyj/Library/Developer/CoreSimulator/Devices/1A092623-6789-42C4-8EB0-DF1777CBE7A5/data/Containers/Data/Application/42E3253A-0D59-42B5-8FF0-ED4C39385278/tmp/CFNetworkDownload_nnzbjb.tmp
location.absoluteURL:---->file:///Users/shenyj/Library/Developer/CoreSimulator/Devices/1A092623-6789-42C4-8EB0-DF1777CBE7A5/data/Containers/Data/Application/42E3253A-0D59-42B5-8FF0-ED4C39385278/tmp/CFNetworkDownload_nnzbjb.tmp
4.1.3 Log图片:
4.2.进度方法,iOS 7.0 必须实现
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite{
/**
bytesWritten 本次下载数据的长度
totalBytesWritten 总共下载的数据的长度 (已经下载了多少)
totalBytesExpectedToWrite 文件的总长度
*/
}
4.3.续传方法
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didResumeAtOffset:(int64_t)fileOffset expectedTotalBytes:(int64_t)expectedTotalBytes {
}
4.4.下载错误监听
NSURLSessionDownloadDelegate 继承自 NSURLSessionTaskDelegate 因此可以直接实现 NSURLSessionTaskDelegate 的代理方法
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error {
}
5. 控制下载任务
分别是:暂停、取消、继续/开始
[self.downloadTask suspend];
[self.downloadTask cancel];
[self.downloadTask resume];
小结:
1.文件下载后,默认存放沙盒tmp路径下,名称随机生成,并在下载完成后自动删除,因此需要在下载完成的代理方法中进行转存
2.与NSURLConnection对比:
2.1 NSURLConnection 通过connectionWithRequest: delegate:设置代理实现方法,添加异步处理后,还需手动开启子线程的消息循环,方法执行完后会自动关闭;而NSURLSession自动异步处理,不许干预,只是创建任务后默认挂起,需要resume;
2.2 NSURLConnection 的下载进度监测实现过程比较复杂,而NSURLSession使用更简便,只需要通过代理方法提供的参数直接使用即可
2.3 NSURLConnection和NSURLSession都可以实现对下载过程可控,包括:开始、暂停、和继续,而NSURLConnection能对程序意外退出再次进入重新下载做出更好的处理