NSURLSessionDownloadDelegate断点下载说明:
- 能实现断点下载,即在程序不退出的情况下:暂停,继续;暂停,继续.
- 但是不能实现离线断点下载.即在下载过程中,程序突然退出.再登陆时不能根据上次下载的进度继续下载.因为系统downloadTask默认保存在沙盒temp中,随时可能被清除,再次登陆时,可能上次保存的下载文件已经被删除.
具体代码如下
@interface ViewController ()<NSURLSessionDownloadDelegate>
@property (weak, nonatomic) IBOutlet UIProgressView *progressView;
/** download data task */
@property (nonatomic, strong) NSURLSessionDownloadTask *downloadTask;
/** 继续下载时,从哪里开始下载 */
@property (nonatomic, strong) NSData *resumeData;
@property (nonatomic, strong) NSURLSession *session;
@end
@implementation ViewController
#pragma mark -------------------------------
#pragma mark lazy load NSURLSession
- (NSURLSession *)session{
if (!_session) {
_session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[NSOperationQueue mainQueue]];
}
return _session;
}
- (void)viewDidLoad {
[super viewDidLoad];
NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/resources/videos/2.mp4"];
self.downloadTask = [self.session downloadTaskWithURL:url];
}
//控制下载下暂停的按钮的点击事件
- (IBAction)playClick:(UIButton *)sender {
sender.selected = !sender.isSelected;
if (sender.selected) {//执行下载操作
if (self.resumeData.length != 0) {
[self resume];
}else{
[self start];
}
}else{//暂停操作
[self suspend];
}
}
- (void)start{
[self.downloadTask resume];
}
- (void)suspend{
//block语句块中引用了self,为防止循环引用,需要弱引用self
__weak typeof(self) weakSelf = self;
[self.downloadTask cancelByProducingResumeData:^(NSData * _Nullable resumeData) {
//resumeData:即为下次下载数据时的开始点,即上次下载的结束点
weakSelf.resumeData = resumeData;
}];
}
- (void)resume{
self.downloadTask = [self.session downloadTaskWithResumeData:self.resumeData];
[self.downloadTask resume];
}
#pragma mark -------------------------------
#pragma mark NSURLSessionDownloadDelegate
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite{
self.progressView.progress = (double)totalBytesWritten / totalBytesExpectedToWrite;
}
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didResumeAtOffset:(int64_t)fileOffset expectedTotalBytes:(int64_t)expectedTotalBytes{
}
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location{
//下载完成后,将下载数据转移至caches
NSString *cachesPath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES)lastObject];
NSString *fullPath = [cachesPath stringByAppendingPathComponent:downloadTask.response.suggestedFilename];
NSFileManager *manager = [NSFileManager defaultManager];
[manager moveItemAtPath:location.path toPath:fullPath error:nil];
}
不能实现离线下载,是专门处理下载任务的downloadTask的bug.可用NSURLSessionDataTask实现.
网友评论