NSURLSession普通多任务下载和断点续传并保存显示进度条

来源:互联网 发布:seo搜索引擎实战详解 编辑:程序博客网 时间:2024/05/01 22:32

关于NSURLSessionde概念的介绍可以参见http://blog.csdn.net/majiakun1/article/details/38133433

在模拟器上测试发现这些下载方式在锁屏或者挂起时也可以下载

普通下载:

都是在viewController里面测试的,定义currentSession的和下载任务downTask这两个属性,使用<NSURLSessionDownloadDelegate>代理方法

为了方便测试 URL是自己搭的服务器上的内容

如果要实现多任务下载 就定义多个task,多个task会同时下载 不同的task用taskIdentifiler进行区分,taskIdentifiler为只读属性,不能赋值,由系统分配其ID值

    NSURLRequest *request=[[NSURLRequest alloc]initWithURL:[NSURL URLWithString:@"http://192.168.23.1/test/Backkom.mp4"]];    NSURLSessionConfiguration *epheSession=[NSURLSessionConfiguration ephemeralSessionConfiguration];    epheSession.discretionary=YES;    self.currentSession=[NSURLSession sessionWithConfiguration:epheSession delegate:self delegateQueue:nil];    self.downTask=[self.currentSession downloadTaskWithRequest:request];    [self.downTask resume];

如果用这种的方式创建task则不会执行NSURLSessionDownloadDelegate中的一些重要的代理方法代理方法,不管成功与否是直接里面的block

self.downTask=[self.currentSession downloadTaskWithRequest:request completionHandler:^(NSURL *location, NSURLResponse *response, NSError *error){        NSLog(@"________");    }];

以下就是NSURLSessionDownloadDelegate中得代理方法,需要注意的时把下载的temp文件转存下来需要自己需要指定文件名和类型;另外注意为指定路径时URL初始化用此方法fileURLWithPath,用URLWithString会造成路径错误

-(void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location{    //下载成功调用此方法,    NSFileManager *fileManager = [NSFileManager defaultManager];//文件管理    NSURL *documentsDirectory=[NSURL fileURLWithPath:[NSHomeDirectory() stringByAppendingString:@"/Documents/"]];    NSURL *destinationPath = [documentsDirectory URLByAppendingPathComponent:@"Backkom.mp4"];    NSError *error;    [fileManager removeItemAtURL:destinationPath error:NULL];//确保文件不在    BOOL success = [fileManager copyItemAtURL:location toURL:destinationPath error:&error];    if(success){        NSLog(@"success path:%@",destinationPath);    }else{        NSLog(@"error:%@",error);    }}
-(void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error{    //失败和成功都会调用    if(error){        NSLog(@"error:%@",error);    }}

执行下载有数据写入执行,bytesWritten--每次写入的data字节数;totalBytesWritten--当前一共写入的data字节数,totalBytesExpectedToWrite--期望收到的所有data字节数

prograss就是下载进度

-(void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite{    double prograss=totalBytesWritten/(double)totalBytesExpectedToWrite;}
如要取消下载可以设置downTask cancel就可以了。

断点续传:

此方式需要定义一个NSData *partialData来存储暂停时需要保存的下载数据,resumableTask为NSURLSessionDownloadTask,当取消下载时,需在cancelByProducingResumeData的block中对已经下载的数据进行保存

if(self.resumableTask){        [self.resumableTask cancelByProducingResumeData:^(NSData *resumeData){            self.partialData=resumeData;        }];    }

创建下载时同样使用的时代理方法,注意判断partiaData,不是nil表示已经取消过下载。代理方法里面的代码和上面普通下载一样

if(!self.resumableTask){        NSURLSessionConfiguration *defaultSession=[NSURLSessionConfiguration defaultSessionConfiguration];        defaultSession.discretionary=YES;        self.resumeSession=[NSURLSession sessionWithConfiguration:defaultSession delegate:self delegateQueue:nil];    }    if(self.partialData){        self.resumableTask=[self.resumeSession downloadTaskWithResumeData:self.partialData];    }else{        NSURLRequest *request=[[NSURLRequest alloc]initWithURL:[NSURL URLWithString:@"http://192.168.23.1/test/Backkom.mp4"]];        self.resumableTask=[self.resumeSession downloadTaskWithRequest:request];    }    [self.resumableTask resume];

后台下载:

后台下载是在说在程序锁屏,挂起也可以下载,甚至在程序退出时都可以继续下载,是由系统来处理的。在找的demo程序我退出程序都不能下载,看backgroundSessionConfigurationWithIdentifier的文档If the user terminates the app from the multitasking screen, the system cancels all of the session’s background transfers说用户终止应用就会取消session的后台就传输,找了个demo(http://www.cocoachina.com/bbs/read.php?tid=171978)也没有实现程序退出后下载成功,希望有成功的同学能分享下或者指教下。



2 0
原创粉丝点击