標籤:ios
具體使用請到我的GitHub
代碼: https://github.com/HHuiHao/HSDownloadManager
功能示範:
—————–代碼實現—————–
開啟任務下載資源方法,新開線程並執行下載任務
- (void)download:(NSString *)url progress:(void (^)(NSInteger, NSInteger, CGFloat))progressBlock state:(void (^)(DownloadState))stateBlock{ // 驗證 if (!url) return; if ([self isCompletion:url]) { stateBlock(DownloadStateCompleted); NSLog(@"----該資源已下載完成"); return; } // 暫停 if ([self.tasks valueForKey:HSFileName(url)]) { [self handle:url]; return; } // 建立緩衝目錄檔案 [self createCacheDirectory]; NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[[NSOperationQueue alloc] init]]; // 建立流 NSOutputStream *stream = [NSOutputStream outputStreamToFileAtPath:HSFileFullpath(url) append:YES]; // 建立請求 NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url]]; // 佈建要求頭 NSString *range = [NSString stringWithFormat:@"bytes=%zd-", HSDownloadLength(url)]; [request setValue:range forHTTPHeaderField:@"Range"]; // 建立一個Data任務 NSURLSessionDataTask *task = [session dataTaskWithRequest:request]; NSUInteger taskIdentifier = arc4random() % ((arc4random() % 10000 + arc4random() % 10000)); [task setValue:@(taskIdentifier) forKeyPath:@"taskIdentifier"]; // 儲存任務 [self.tasks setValue:task forKey:HSFileName(url)]; HSSessionModel *sessionModel = [[HSSessionModel alloc] init]; sessionModel.url = url; sessionModel.progressBlock = progressBlock; sessionModel.stateBlock = stateBlock; sessionModel.stream = stream; [self.sessionModels setValue:sessionModel forKey:@(task.taskIdentifier).stringValue]; [self start:url];}
分解方法:
if (!url) return; if ([self isCompletion:url]) { stateBlock(DownloadStateCompleted); NSLog(@"----該資源已下載完成"); return; } // 暫停 if ([self.tasks valueForKey:HSFileName(url)]) { [self handle:url]; return; }
NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[[NSOperationQueue alloc] init]];
NSOutputStream *stream = [NSOutputStream outputStreamToFileAtPath:HSFileFullpath(url) append:YES];
// 建立請求NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url]];// 佈建要求頭NSString *range = [NSString stringWithFormat:@"bytes=%zd-", HSDownloadLength(url)];[request setValue:range forHTTPHeaderField:@"Range"];
- 並建立一個data任務:NSURLSessionDataTask
NSURLSessionDataTask *task = [session dataTaskWithRequest:request];NSUInteger taskIdentifier = arc4random() % ((arc4random() % 10000 + arc4random() % 10000));[task setValue:@(taskIdentifier) forKeyPath:@"taskIdentifier"];
- 儲存每個NSURLSessionDataTask任務:self.tasks
[self.tasks setValue:task forKey:HSFileName(url)];
- 相關請求資訊回調方法封裝到model: HSSessionModel
```objcHSSessionModel *sessionModel = [[HSSessionModel alloc] init];sessionModel.url = url;sessionModel.progressBlock = progressBlock;sessionModel.stateBlock = stateBlock;sessionModel.stream = stream;[self.sessionModels setValue:sessionModel forKey:@(task.taskIdentifier).stringValue];[self start:url];
接收處理資料 NSURLSessionDataDelegate接收資料
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSHTTPURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler{ HSSessionModel *sessionModel = [self getSessionModel:dataTask.taskIdentifier]; // 開啟流 [sessionModel.stream open]; // 獲得伺服器這次請求 返回資料的總長度 NSInteger totalLength = [response.allHeaderFields[@"Content-Length"] integerValue] + HSDownloadLength(sessionModel.url); sessionModel.totalLength = totalLength; // 儲存總長度 NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithContentsOfFile:HSTotalLengthFullpath]; if (dict == nil) dict = [NSMutableDictionary dictionary]; dict[HSFileName(sessionModel.url)] = @(totalLength); [dict writeToFile:HSTotalLengthFullpath atomically:YES]; // 接收這個請求,允許接收伺服器的資料 completionHandler(NSURLSessionResponseAllow);}
接收到伺服器返回的資料
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data{ // 擷取模型 HSSessionModel *sessionModel = [self getSessionModel:dataTask.taskIdentifier]; // 寫入資料 [sessionModel.stream write:data.bytes maxLength:data.length]; // 下載進度 NSUInteger receivedSize = HSDownloadLength(sessionModel.url); NSUInteger expectedSize = sessionModel.totalLength; CGFloat progress = 1.0 * receivedSize / expectedSize; // block回調 sessionModel.progressBlock(receivedSize, expectedSize, progress);}
請求完畢(成功或失敗)
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error{ HSSessionModel *sessionModel = [self getSessionModel:task.taskIdentifier]; if (!sessionModel) return; if ([self isCompletion:sessionModel.url]) { // 下載完成 sessionModel.stateBlock(DownloadStateCompleted); } else if (error){ // 下載失敗 sessionModel.stateBlock(DownloadStateFailed); } // 關閉流 [sessionModel.stream close]; sessionModel.stream = nil; // 清除任務 [self.tasks removeObjectForKey:HSFileName(sessionModel.url)]; [self.sessionModels removeObjectForKey:@(task.taskIdentifier).stringValue];}
著作權聲明:本文為博主原創文章,未經博主允許不得轉載。
iOS 支援多任務、斷點下載(圖片、音頻、視頻) (Demo 一)