檔案下載的三種方式,看這裡就已經足夠了。
阿新 • • 發佈:2019-01-31
檔案下載一(不支援斷點續傳)
這種下載方式用的場合比較少,邏輯比較複雜,程式碼量也比較大。
主要的處理在兩個代理方法中
-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{ if (self.currentLength) return; //檔案路徑 NSString * caches = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject]; NSString * filepath = [caches stringByAppendingPathComponent:@"file.zip"]; NSLog(@"%@",filepath); _path = filepath; //建立一個空的檔案到沙河中 NSFileManager * mgr = [NSFileManager defaultManager]; [mgr createFileAtPath:filepath contents:nil attributes:nil]; //建立一個用來寫資料的檔案控制代碼 self.writeHandle = [NSFileHandle fileHandleForWritingAtPath:filepath]; //獲取檔案的大小 self.totalLength = response.expectedContentLength; NSLog(@"--%lld",self.totalLength); // 68186536 }
/** * 2.當接收到伺服器返回的實體資料時呼叫(具體內容,這個方法可能會被呼叫多次) * * @param data 這次返回的資料 */ -(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{ //移動到檔案的最後面 [self.writeHandle seekToEndOfFile]; //將資料寫入到沙河 [self.writeHandle writeData:data]; // NSLog(@"%@",data); //累計檔案的長度 self.currentLength += data.length; self.speed = [CountBytes CountBytesBy:data.length]; self.CircleView.progress = (double)self.currentLength/ self.totalLength; }
檔案下載二(支援斷點續傳)
所謂斷點續傳就是在某個時刻暫停後,再次下載的時候從之前的進度開始,這就需要我們記錄下暫停之前下載資料。
ok,我們只看暫停和再次開始的程式碼
暫停的程式碼
- (IBAction)pauseClicked:(id)sender {
[self.task cancelByProducingResumeData:^(NSData * _Nullable resumeData) {
_resumeData = resumeData;
_task = nil;
}];
}
再次恢復下載的程式碼
- (IBAction)continueClicked:(id)sender{ self.task = [self.session downloadTaskWithResumeData:self.resumeData]; [self.task resume]; self.resumeData = nil; }
檔案下載三(支援斷點續傳)
這種下載方式是站在巨人的肩膀上,這個巨人就是偉大的AFN,在這裡我將其封裝成了下載工具類,只需要傳下載路徑就ok,然後根據block返回的資料進行重新整理執行緒。
核心程式碼
+ (NSURLSessionDownloadTask *)downloadFileWithUrl:(NSString *)url DownloadProgress:(DownloadProgress)progress DownloadCompletion:(CompletionState)completion{
// 1、 設定請求
NSURLRequest * request = [NSURLRequest requestWithURL:[NSURL URLWithString:url]];
// 2、初始化
NSURLSessionConfiguration * configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
AFURLSessionManager * manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration];
// 3、開始下載
NSURLSessionDownloadTask * task = [manager downloadTaskWithRequest:request progress:^(NSProgress * _Nonnull downloadProgress) {
progress(1.0 * downloadProgress.completedUnitCount / downloadProgress.totalUnitCount,1.0 * downloadProgress.totalUnitCount,1.0 * downloadProgress.completedUnitCount);
} destination:^NSURL * _Nonnull(NSURL * _Nonnull targetPath, NSURLResponse * _Nonnull response) {
//這裡要返回一個NSURL,其實就是檔案的位置路徑
NSString * path = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
//使用建議的路徑
path = [path stringByAppendingPathComponent:response.suggestedFilename];
NSLog(@"%@",path);
return [NSURL fileURLWithPath:path];//轉化為檔案路徑
} completionHandler:^(NSURLResponse * _Nonnull response, NSURL * _Nullable filePath, NSError * _Nullable error) {
//如果下載的是壓縮包的話,可以在這裡進行解壓
NSLog(@"----%@---%d---%@",error.domain,error.code,error);
//下載成功
if (error == nil) {
completion(YES,@"下載完成",[filePath path]);
}else{//下載失敗的時候,只列舉判斷了兩種錯誤狀態碼
NSString * message = nil;
if (error.code == - 1005) {
message = @"網路異常";
}else if (error.code == -1001){
message = @"請求超時";
}else{
message = @"未知錯誤";
}
completion(NO,message,nil);
}
}];
return task;
}
程式碼傳送門:https://github.com/fuzongjian/DownloadStudy.git,順手給個star以資鼓勵,贈人玫瑰。