网络编程05-通过NSURLSessionDownloadTask来下载

版权所有,禁止匿名转载;禁止商业使用。

这里介绍NSURLSessionDownloadTask的两种下载文件的方式.一种是block形式的,代码精简,但是无法控制下载进度,以及断点下载.
第二种是delegate的形式,功能强大,既可以控制下载进度,又可以设置断点下载.
在项目中 大家可以根据需要选择最佳的实践方案:

1.NSURLSessionDownloadTask的block形式.

- (NSURLSessionDownloadTask *)downloadTaskWithRequest:(NSURLRequest *)request completionHandler:(void (^)(NSURL *location, NSURLResponse *response, NSError *error))completionHandler

downloadTaskWithURL: 该方法默认已经实现了边下载边写入.所以在 completionHandler 这个 block 里,我们需要把文件从一个临时地址移动到一个永久的地址保存起来.通过指定 completionHandler 这个 block 将创建一个隐式的 delegate,来替代该 task 原来的 delegate——session。
参数解释:
第一个参数: 需要下载的文件的路径

第二个参数:

  • location: 下载好的文件在手机磁盘上的位置,临时存储
  • response: 响应头
  • error: 请求是否有错

其他两种block形式分别根据url,还有恢复数据来创建相应的
NSURLSessionDownloadTask.如下所示:

- (NSURLSessionDownloadTask *)downloadTaskWithURL:(NSURL *)url completionHandler:(void (^)(NSURL *location, NSURLResponse *response, NSError *error))completionHandler  - (NSURLSessionDownloadTask *)downloadTaskWithResumeData:(NSData *)resumeData completionHandler:(void (^)(NSURL *location, NSURLResponse *response, NSError *error))completionHandler 

下面是一个下载image的实例,然后把image移动

    // 1.创建NSURLSession     NSURLSession *session = [NSURLSession sharedSession];     // 2.创建Task     NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/resources/images/minion_02.png"];     NSURLSessionDownloadTask *task = [session downloadTaskWithURL:url completionHandler:^(NSURL *location, NSURLResponse *response, NSError *error) {         NSString *dir = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];         // 1.生成需要移动到得路径         NSString *toPath = [dir stringByAppendingPathComponent:[response.suggestedFilename lastPathComponent]];         NSLog(@"%@",toPath);         // 2.移动文件         NSFileManager *manager = [NSFileManager defaultManager];         [manager moveItemAtURL:location toURL:[NSURL fileURLWithPath:toPath] error:nil];     }];     // 3.启动任务     [task resume];

2.使用delegate进行下载


这里写图片描述

#import "ViewController.h"  @interface ViewController ()<NSURLSessionDownloadDelegate>  @property (weak, nonatomic) IBOutlet UIProgressView *progressView; - (IBAction)startBtnClick:(UIButton *)sender; - (IBAction)pauseBtnClick:(UIButton *)sender; - (IBAction)goOnBtnClick:(UIButton *)sender;  /** 任务 */ @property (nonatomic, strong) NSURLSessionDownloadTask *task;  /** session */ @property (nonatomic, strong) NSURLSession *session;  /** 恢复信息 */ @property (nonatomic, strong) NSData *resumeData; @end  @implementation ViewController  - (IBAction)startBtnClick:(UIButton *)sender {      // 1.创建NSURLSession     NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[NSOperationQueue mainQueue]];     self.session = session;      // 2.创建Task     NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/resources/videos/minion_02.mp4"];     self.task = [session downloadTaskWithURL:url];      // 3.启动任务     [self.task resume]; }  - (IBAction)pauseBtnClick:(UIButton *)sender {     // resumeData : 保存了当前用户下载的信息     // 只要有了这些信息, 以后就可以通过这些信息恢复下载     [self.task cancelByProducingResumeData:^(NSData *resumeData) {         self.resumeData = resumeData;     }]; }  - (IBAction)goOnBtnClick:(UIButton *)sender {     self.task = [self.session downloadTaskWithResumeData:self.resumeData];     [self.task resume];  }  #pragma mark - NSURLSessionDownloadDelegate /*  1.接收到服务器返回的数据  正在写入数据  bytesWritten: 当前这一次写入的数据大小  totalBytesWritten: 已经写入到本地文件的总大小  totalBytesExpectedToWrite : 被下载文件的总大小  */  - (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite {     self.progressView.progress = 1.0 * totalBytesWritten / totalBytesExpectedToWrite; }  /*  2.恢复下载时调用  fileOffset : 恢复之后要从文件的什么地方开始写入数据  expectedTotalBytes: 文件总共需要下载的大小  */ - (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didResumeAtOffset:(int64_t)fileOffset expectedTotalBytes:(int64_t)expectedTotalBytes {     NSLog(@"fileOffset = %lld, expectedTotalBytes = %lld", fileOffset, expectedTotalBytes); }  //3.下载完成 - (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location {     // 1.生成需要移动到得路径     NSString *dir = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];     NSString *toPath = [dir stringByAppendingPathComponent:downloadTask.response.suggestedFilename];     // 2.移动文件     NSFileManager *manager = [NSFileManager defaultManager];     [manager moveItemAtURL:location toURL:[NSURL fileURLWithPath:toPath] error:nil]; }  //4.请求完毕,如果有错误, 那么error有值 - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error {     NSLog(@"didCompleteWithError"); }  @end
 查看演示        立即下载
0 0