iOS 使用AFNetworking進行下載和上傳
阿新 • • 發佈:2018-11-06
AFNetworking為我們提供了太多的方便,今天說一下用AFNetworking進行檔案的下載和上傳,AFNetworking的引入就不多說了
首先,在storyboard的view上新增一個imageview和一個button,分別增加輸出口和點選事件
在ViewController.m中引入標頭檔案#import<AFNetworking.h>
然後在button點選事件中加入下載方法
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration]; AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration]; NSURL *URL = [NSURL URLWithString:@"https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1504497234144&di=a3169e58078bb55ae38bfc99fd18f17e&imgtype=jpg&src=http%3A%2F%2Fg.hiphotos.baidu.com%2Fimage%2Fpic%2Fitem%2F8694a4c27d1ed21bd85def25a46eddc450da3f5e.jpg"]; NSURLRequest *request = [NSURLRequest requestWithURL:URL]; NSURLSessionDownloadTask *downloadTask = [manager downloadTaskWithRequest:request progress:^(NSProgress *downloadProgress){ // 這個block裡面獲取下載進度 [SVProgressHUD showProgress:(CGFloat)downloadProgress.completedUnitCount/(CGFloat)downloadProgress.totalUnitCount status:@"下載中"]; } destination:^NSURL *(NSURL *targetPath, NSURLResponse *response) { // 這個block裡面返回下載檔案存放路徑 if([self isFileExist:[response suggestedFilename]]) { NSLog(@"檔案已存在"); } NSURL *documentsDirectoryURL = [[NSFileManager defaultManager] URLForDirectory:NSDocumentDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:NO error:nil]; // [response suggestedFilename]為檔名 NSURL *url = [documentsDirectoryURL URLByAppendingPathComponent:[response suggestedFilename]]; return url; } completionHandler:^(NSURLResponse *response, NSURL *filePath, NSError *error) { // 這個block裡面拿到下載結果 NSData *data = [NSData dataWithContentsOfURL:filePath]; UIImage *img = [UIImage imageWithData:data]; self.imageView.image = img; [SVProgressHUD dismissWithDelay:0.0 completion:nil]; }]; [downloadTask resume];
//判斷檔案是否已經在沙盒中存在
-(BOOL) isFileExist:(NSString *)fileName
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *path = [paths objectAtIndex:0];
NSString *filePath = [path stringByAppendingPathComponent:fileName];
NSFileManager *fileManager = [NSFileManager defaultManager];
BOOL result = [fileManager fileExistsAtPath:filePath];
NSLog(@"這個檔案已經存在:%@", [email protected]"是的":@"不存在");
return result;
}
上傳,因為沒有伺服器,就只能把自己用過的方法寫下來,希望能對需要的朋友有所幫助
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager]; manager.responseSerializer = [AFHTTPResponseSerializer serializer]; [manager POST:@"https://pan.baidu.com/disk/home#list/vmode=list&path=%2Fsz" parameters:nil constructingBodyWithBlock:^(id<AFMultipartFormData> _Nonnull formData) { NSURL *documentsDirectoryURL = [[NSFileManager defaultManager] URLForDirectory:NSDocumentDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:NO error:nil]; // self.fileName為要上傳檔案的檔名 NSURL *filePath = [documentsDirectoryURL URLByAppendingPathComponent:self.fileName]; //上傳 /* 此方法引數 1. 要上傳的data資料 2. 後臺處理檔案的欄位,若沒有可為空 3. 要儲存在伺服器上的[檔名] 4. 上傳檔案的[mimeType] application/octet-stream為通用型 */ // [formData appendPartWithFileData:fileData name:@"file" fileName:self.fileName mimeType:@"application/octet-stream"]; /* 此方法引數 1. 要上傳的檔案路徑 2. 後臺處理檔案的欄位,若沒有可為空 3. 要儲存在伺服器上的[檔名] 4. 上傳檔案的[mimeType] application/octet-stream為通用型 */ [formData appendPartWithFileURL:filePath name:@"file" fileName:self.fileName mimeType:@"application/octet-stream" error:nil]; //個人比較建議用第二種,傳檔案路徑,因為自己做上傳當時的場景是把wps編輯後的文件上傳到伺服器,因為回傳回來的是一個字典,我就直接將字典內容解析出來轉成data資料,但是上傳到伺服器後文檔開啟時提示檔案損壞,下載下來開啟是亂碼,推測應該是wps回傳回來的資料裡應該有自己的一些編碼在裡面,導致直接上傳data資料會出現後臺解析錯誤的問題,後來把回傳回來的資料轉成檔案之後,再用檔案路徑方法上傳就沒問題了。 } progress:^(NSProgress * _Nonnull uploadProgress) { } success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) { [SVProgressHUD showSuccessWithStatus:@"上傳成功"]; } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) { [SVProgressHUD showErrorWithStatus:@"上傳失敗"]; }];
上面的上傳地址是我自己的百度雲盤,雖然沒報錯,但是沒上傳到雲盤裡,只是作為示範。