iOS之文件断点下载
#define ResumeDataFile [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:@"resumeData.tmp"] #import "ViewController.h" @interface ViewController () <NSURLSessionDownloadDelegate> /** 下载任务 */ @property (nonatomic, strong) NSURLSessionDownloadTask *task; /** 保存上次的下载信息 */ @property (nonatomic, strong) NSData *resumeData; /** session */ @property (nonatomic, strong) NSURLSession *session; @end @implementation ViewController - (NSURLSession *)session { if (!_session) { _session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[[NSOperationQueue alloc] init]]; } return _session; } //- (NSData *)resumeData //{ // if (!_resumeData) { // _resumeData = [NSData dataWithContentsOfFile:ResumeDataFile]; // } // return _resumeData; //} /** * 开始下载 */ - (IBAction)start:(id)sender { // if (self.resumeData) { // // 获得上次的下载任务 // self.task = [self.session downloadTaskWithResumeData:self.resumeData]; // // // 将上次的临时文件放到tmp中 // // } else { // 获得下载任务 self.task = [self.session downloadTaskWithURL:[NSURL URLWithString:@"http://120.25.226.186:32812/resources/videos/minion_01.mp4"]]; // } // 启动任务 [self.task resume]; } /** * 暂停下载 */ - (IBAction)pause:(id)sender { // 一旦这个task被取消了,就无法再恢复 [self.task cancelByProducingResumeData:^(NSData *resumeData) { self.resumeData = resumeData; // // // 可以将resumeData写入沙盒,保存起来 // // 下次进入程序,就可以将resumeData读取进来,继续下载 // [resumeData writeToFile:ResumeDataFile atomically:YES]; // // // caches文件夹 // NSString *caches = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject]; // // // 缓存文件 // NSString *tmp = NSTemporaryDirectory(); // NSFileManager *mgr = [NSFileManager defaultManager]; // NSArray *subpaths = [mgr subpathsAtPath:tmp]; // NSString *file = [tmp stringByAppendingPathComponent:[subpaths lastObject]]; // NSString *cachesTempFile = [caches stringByAppendingPathComponent:[file lastPathComponent]]; // [mgr moveItemAtPath:file toPath:cachesTempFile error:nil]; // // [@{@"tempFile" : cachesTempFile} writeToFile:[caches stringByAppendingPathComponent:@"tempFile.plist"] atomically:YES]; }]; } /**x 请求这个路径:http://120.25.226.186:32812/resources/videos/minion_01.mp4 设置请求头 Range : 1024-2000 */ /** * 继续下载 */ - (IBAction)goOn:(id)sender { self.task = [self.session downloadTaskWithResumeData:self.resumeData]; [self.task resume]; } #pragma mark - <NSURLSessionDownloadDelegate> - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error { NSLog(@"didCompleteWithError"); // 保存恢复数据 self.resumeData = error.userInfo[NSURLSessionDownloadTaskResumeData]; } - (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didResumeAtOffset:(int64_t)fileOffset expectedTotalBytes:(int64_t)expectedTotalBytes { NSLog(@"didResumeAtOffset"); } /** * 每当写入数据到临时文件时,就会调用一次这个方法 * totalBytesExpectedToWrite:总大小 * totalBytesWritten: 已经写入的大小 * bytesWritten: 这次写入多少 */ - (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite { NSLog(@"--------%f", 1.0 * totalBytesWritten / totalBytesExpectedToWrite); } /** * * 下载完毕就会调用一次这个方法 */ - (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location { // 文件将来存放的真实路径 NSString *file = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:downloadTask.response.suggestedFilename]; // 剪切location的临时文件到真实路径 NSFileManager *mgr = [NSFileManager defaultManager]; [mgr moveItemAtURL:location toURL:[NSURL fileURLWithPath:file] error:nil]; } @end