1 // 2 // ViewController.m 3 // 03-DownloadTask 4 // 5 //如果退出程序后仍能实现断点续传,思路: 6 //1.保存resumeData到本地沙盒路径。 7 //2.分析resumeData是如何记录下载文件信息的。才能设定下次进入时进度条的进度。 8 9 #import "ViewController.h" 10 11 @interface ViewController () <NSURLSessionDownloadDelegate> { 12 NSURLSessionDownloadTask *_downloadTask; //下载任务 13 NSData *_savedResumeData; //已下载的数据信息 14 15 NSURLSession *_downloadSession; //会话对象,可发起多个任务 16 } 17 18 @end 19 20 @implementation ViewController 21 22 - (void)viewDidLoad { 23 [super viewDidLoad]; 24 // Do any additional setup after loading the view, typically from a nib. 25 } 26 27 - (void)didReceiveMemoryWarning { 28 [super didReceiveMemoryWarning]; 29 // Dispose of any resources that can be recreated. 30 } 31 32 - (void)moveDownloadFile:(NSURL *)location ToPath:(NSString *)targetFilePath { 33 34 //目标路径 35 NSString *filePath = [NSHomeDirectory() stringByAppendingPathComponent:targetFilePath]; 36 37 NSFileManager *manager = [NSFileManager defaultManager]; 38 39 //判断目标路径下的文件是否存在,如果不存在,则剪切 40 BOOL exist = [manager fileExistsAtPath:filePath]; 41 if (!exist) { 42 43 [manager moveItemAtURL:location toURL:[NSURL fileURLWithPath:filePath] error:nil]; 44 } 45 46 NSLog(@"文件保存成功"); 47 48 49 } 50 51 //普通下载任务 52 - (IBAction)commonDownloadAction:(id)sender { 53 54 NSURL *url = [NSURL URLWithString:@"http://218.76.27.57:8080/chinaschool_rs02/135275/153903/160861/160867/1370744550357.mp3"]; 55 56 NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration]; 57 58 _downloadSession = [NSURLSession sessionWithConfiguration:config delegate:self delegateQueue:[NSOperationQueue mainQueue]]; 59 60 _downloadTask = [_downloadSession downloadTaskWithURL:url]; 61 62 [_downloadTask resume]; 63 64 65 } 66 67 //暂停下载 68 - (IBAction)pauseAction:(id)sender { 69 70 if (_downloadTask) { 71 72 if (_downloadTask.state == NSURLSessionTaskStateRunning) { 73 74 //cancle后此任务停止,不能再恢复。 75 //[_downloadTask cancel]; 76 [_downloadTask cancelByProducingResumeData:^(NSData * _Nullable resumeData) { 77 //resumeData记录了已下载文件的信息,并非记载下载文件的全部数据。 78 //记录任务取消时提供的信息。 79 _savedResumeData = resumeData; 80 81 //此任务取消后下次会创建一个新的任务,此时应该释放旧任务 82 _downloadTask = nil; 83 84 }]; 85 86 } 87 88 } 89 90 } 91 92 //恢复下载 93 - (IBAction)resumeAction:(id)sender { 94 95 if (_savedResumeData) { 96 97 //重新发起一个任务,但是是根据之前cancel的任务发起的,通过resumeData来保存之前任务的状态。 98 _downloadTask = [_downloadSession downloadTaskWithResumeData:_savedResumeData]; 99 100 //释放resumeData 101 _savedResumeData = nil; 102 103 [_downloadTask resume]; 104 } 105 } 106 107 108 #pragma mark - NSURLSessionDownloadDelegate 109 110 //下载完成时调用 111 - (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask 112 didFinishDownloadingToURL:(NSURL *)location { 113 114 NSLog(@"location:%@", location); 115 116 117 //把临时目录下的文件剪切到目标文件夹。 118 [self moveDownloadFile:location ToPath:@"Documents/jay.mp3"]; 119 120 121 _downloadTask = nil; 122 _downloadSession = nil; 123 124 125 } 126 127 //监听下载进度,此协议方法可能会被调用多次 128 /* 129 bytesWritten:本次传输下载了多少字节 130 totalBytesWritten:已经下载了多少字节 131 totalBytesExpectedToWrite:文件的总大小 132 133 */ 134 - (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask 135 didWriteData:(int64_t)bytesWritten 136 totalBytesWritten:(int64_t)totalBytesWritten 137 totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite { 138 139 float progress = (float)totalBytesWritten / totalBytesExpectedToWrite; 140 self.progressView.progress = progress; 141 self.progressLable.text = [NSString stringWithFormat:@"%.2f%%", progress * 100]; 142 143 144 145 } 146 @end