对于断点下载需要考虑几个问题:
- 如何暂停下载,暂停后,如何继续下载?
- 下载失败后,如何恢复下载?
- 应用被用户杀掉后,如何恢复之前的下载?
第一种方法
使用cancelByProducingResumeData
/* 对某一个NSURLSessionDownloadTask取消下载,取消后会回调给我们 resumeData,
* resumeData包含了下载任务的一些状态,之后可以用户恢复下载
*/
- (void)cancelByProducingResumeData:(void (^)(NSData * resumeData))completionHandler;
调用该方法会触发以下方法,会附带resumeData
,用于恢复。
- (void)URLSession:(NSURLSession *)session
task:(NSURLSessionTask *)task
didCompleteWithError:(NSError *)error
恢复下载的方法
//通过之前保存的resumeData,获取断点的NSURLSessionTask,调用resume恢复下载
NSURLSessionDownloadTask *task = [[self backgroundURLSession] downloadTaskWithResumeData:resumeData];
[task resume];
第二种方法
使用NSURLSessionDownloadTask
的suspend
方法
//暂停
[self.downloadTask suspend];
//恢复
[self.downloadTask resume];
/* 该方法下载成功和失败都会回调,只是失败的是error是有值的,
* 在下载失败时,error的userinfo属性可以通过NSURLSessionDownloadTaskResumeData
* 这个key来取到resumeData(和上面的resumeData是一样的),再通过resumeData恢复下载
*/
- (void)URLSession:(NSURLSession *)sessiona
task:(NSURLSessionTask *)task
didCompleteWithError:(NSError *)error {
if (error) {
// check if resume data are available
if ([error.userInfo objectForKey:NSURLSessionDownloadTaskResumeData]) {
NSData *resumeData = [error.userInfo objectForKey:NSURLSessionDownloadTaskResumeData];
NSURLSessionTask *task = [[self backgroundURLSession] downloadTaskWithResumeData:resumeData];
[task resume];
}
}
}
在应用被杀掉前,iOS系统保存应用下载sesson的信息,在重新启动应用,并且创建和之前相同identifier
的session
时(苹果通过identifier
找到对应的session数据),iOS系统会对之前下载中的任务进行依次回调URLSession:task:didCompleteWithError:
方法,之后可以使用上面提到的下载失败时的处理方法进行恢复下载
**PS:**以上是对于NSURLSession
,那么在iOS7.0之前使用NSURLConnection
则应该新增一个currentLength
属性,时刻记录当前下载文件的长度。然后下载时通过设置http头``Range
将当前进度传过去。告诉服务端从哪开始下载。
NSMutableURLRequest *mRequest = [NSMutableURLRequest requestWithURL:url];
NSString *range = [NSString stringWithFormat:@"bytes=%lld-",self.currentLength];
[mRequest setValue:range forHTTPHeaderField:@"Range"];