#import "ViewController.h" #import "AFNetworking.h" @interface ViewController () @end @implementation ViewController -(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event { [self download]; } -(void)download { //1.創建會話管理者 AFHTTPSessionManager *manager =[AFHTTPSessionManager manager]; NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/resources/videos/minion_01.mp4"]; NSURLRequest *request = [NSURLRequest requestWithURL:url]; //2.下載文件 /* 第一個參數:請求對象 第二個參數:progress 進度回調 downloadProgress 第三個參數:destination 回調(目標位置) 有返回值 targetPath:臨時文件路徑 response:響應頭信息 第四個參數:completionHandler 下載完成之后的回調 filePath:最終的文件路徑 */ /* 第一個參數:請求對象 第二個參數:進度回調 downloadProgress.completedUnitCount :已經下載的數據 downloadProgress.totalUnitCount:數據的總大小 第三個參數:destination回調,該block需要返回值(NSURL類型),告訴系統應該把文件剪切到什么地方 targetPath:文件的臨時保存路徑tmp,隨時可能被刪除 response:響應頭信息 第四個參數:completionHandler請求完成后回調 response:響應頭信息 filePath:文件的保存路徑,即destination回調的返回值 error:錯誤信息 */ NSURLSessionDownloadTask *download = [manager downloadTaskWithRequest:request progress:^(NSProgress * _Nonnull downloadProgress) { //監聽下載進度 //completedUnitCount 已經下載的數據大小 //totalUnitCount 文件數據的中大小 NSLog(@"%f",1.0 *downloadProgress.completedUnitCount / downloadProgress.totalUnitCount); } destination:^NSURL * _Nonnull(NSURL * _Nonnull targetPath, NSURLResponse * _Nonnull response) { /** * 1:1:請求路徑:NSUrl *url = [NSUrl urlWithString:path];從網絡請求路徑 2:把本地的file文件路徑轉成url,NSUrl *url = [NSURL fileURLWithPath:fullPath]; 2:返回值是一個下載文件的路徑 * */ NSString *fullPath = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:response.suggestedFilename]; NSLog(@"targetPath:%@",targetPath); NSLog(@"fullPath:%@",fullPath); return [NSURL fileURLWithPath:fullPath]; } completionHandler:^(NSURLResponse * _Nonnull response, NSURL * _Nullable filePath, NSError * _Nullable error) { /** *filePath:下載后文件的保存路徑 */ NSLog(@"%@",filePath); }]; //3.執行Task [download resume]; } @end
(2)使用AFN下載文件
```objc
-(void)download
{
//1.創建會話管理者
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
//2.創建請求對象
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://120.25.226.186:32812/resources/images/minion_13.png"]];
//3.創建下載Task
/*
第一個參數:請求對象
第二個參數:進度回調
downloadProgress.completedUnitCount :已經下載的數據
downloadProgress.totalUnitCount:數據的總大小
第三個參數:destination回調,該block需要返回值(NSURL類型),告訴系統應該把文件剪切到什么地方
targetPath:文件的臨時保存路徑
response:響應頭信息
第四個參數:completionHandler請求完成后回調
response:響應頭信息
filePath:文件的保存路徑,即destination回調的返回值
error:錯誤信息
*/
NSURLSessionDownloadTask *downloadTask = [manager downloadTaskWithRequest:request progress:^(NSProgress * _Nonnull downloadProgress) {
NSLog(@"%f",1.0 * downloadProgress.completedUnitCount / downloadProgress.totalUnitCount);
} destination:^NSURL * _Nonnull(NSURL * _Nonnull targetPath, NSURLResponse * _Nonnull response) {
NSString *fullPath = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:response.suggestedFilename];
NSLog(@"%@\n%@",targetPath,fullPath);
return [NSURL fileURLWithPath:fullPath];
} completionHandler:^(NSURLResponse * _Nonnull response, NSURL * _Nullable filePath, NSError * _Nullable error) {
NSLog(@"%@",filePath);
}];
//4.執行Task
[downloadTask resume];
}
```
二:文件上傳
#import "ViewController.h" #import "AFNetworking.h" #define Kboundary @"----WebKitFormBoundaryjv0UfA04ED44AhWx" #define KNewLine [@"\r\n" dataUsingEncoding:NSUTF8StringEncoding] @interface ViewController () @end @implementation ViewController -(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event { [self upload2]; } //不推薦 -(void)upload { //1.創建會話管理者 AFHTTPSessionManager *manager = [AFHTTPSessionManager manager]; //2.1url NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/upload"]; //2.2創建請求對象 NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; //2.3 設置請求方法 request.HTTPMethod = @"POST"; //2.4 設請求頭信息 [request setValue:[NSString stringWithFormat:@"multipart/form-data; boundary=%@",Kboundary] forHTTPHeaderField:@"Content-Type"]; //3.發送請求上傳文件 NSURLSessionUploadTask *uploadTask = [manager uploadTaskWithRequest:request fromData:[self getBodyData] progress:^(NSProgress * _Nonnull uploadProgress) { NSLog(@"%f",1.0 * uploadProgress.completedUnitCount/ uploadProgress.totalUnitCount); } completionHandler:^(NSURLResponse * _Nonnull response, id _Nullable responseObject, NSError * _Nullable error) { NSLog(@"%@",responseObject); }]; //4.執行task [uploadTask resume]; } -(void)upload2 { //1.創建會話管理者 AFHTTPSessionManager *manager = [AFHTTPSessionManager manager]; // NSDictionary *dictM = @{} //2.發送post請求上傳文件 /* 第一個參數:請求路徑 第二個參數:字典(非文件參數) 第三個參數:constructingBodyWithBlock 處理要上傳的文件數據 第四個參數:進度回調 第五個參數:成功回調 responseObject:響應體信息 第六個參數:失敗回調 */ [manager POST:@"http://120.25.226.186:32812/upload" parameters:nil constructingBodyWithBlock:^(id<AFMultipartFormData> _Nonnull formData) { /** * 1:將image轉換成NSData:可用 UIImagePNGRepresentation,也可用UIImageJPEGRepresentation 2:data轉換成image:UIImage *image = [UIImage imageWithData:data]; 3:url:1;網絡路徑:NSUrl urlWithString 2:NSUrl fileUrlWithStr:本地文件路徑 4:第三種方法:沒有傳fileName 和 mimeType,由AFN內部去自動設置,fileName截取的文件的url路徑,mimeType由c語言內部去獲取 */ UIImage *image = [UIImage imageNamed:@"Snip20160227_128"]; NSData *imageData = UIImagePNGRepresentation(image); //使用formData來拼接數據 /* 第一個參數:二進制數據 要上傳的文件參數 第二個參數:服務器規定的 第三個參數:該文件上傳到服務器以什么名稱保存 */ //[formData appendPartWithFileData:imageData name:@"file" fileName:@"xxxx.png" mimeType:@"image/png"]; //[formData appendPartWithFileURL:[NSURL fileURLWithPath:@"/Users/xiaomage/Desktop/Snip20160227_128.png"] name:@"file" fileName:@"123.png" mimeType:@"image/png" error:nil]; [formData appendPartWithFileURL:[NSURL fileURLWithPath:@"/Users/xiaomage/Desktop/Snip20160227_128.png"] name:@"file" error:nil]; } progress:^(NSProgress * _Nonnull uploadProgress) { NSLog(@"%f",1.0 * uploadProgress.completedUnitCount/uploadProgress.totalUnitCount); } success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) { NSLog(@"上傳成功---%@",responseObject); } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) { NSLog(@"上傳失敗---%@",error); }]; } -(NSData *)getBodyData { NSMutableData *fileData = [NSMutableData data]; //5.1 文件參數 /* --分隔符 Content-Disposition: form-data; name="file"; filename="Snip20160225_341.png" Content-Type: image/png(MIMEType:大類型/小類型) 空行 文件參數 */ [fileData appendData:[[NSString stringWithFormat:@"--%@",Kboundary] dataUsingEncoding:NSUTF8StringEncoding]]; [fileData appendData:KNewLine]; //name:file 服務器規定的參數 //filename:Snip20160225_341.png 文件保存到服務器上面的名稱 //Content-Type:文件的類型 [fileData appendData:[@"Content-Disposition: form-data; name=\"file\"; filename=\"Sss.png\"" dataUsingEncoding:NSUTF8StringEncoding]]; [fileData appendData:KNewLine]; [fileData appendData:[@"Content-Type: image/png" dataUsingEncoding:NSUTF8StringEncoding]]; [fileData appendData:KNewLine]; [fileData appendData:KNewLine]; UIImage *image = [UIImage imageNamed:@"Snip20160227_128"]; //UIImage --->NSData NSData *imageData = UIImagePNGRepresentation(image); [fileData appendData:imageData]; [fileData appendData:KNewLine]; //5.2 非文件參數 /* --分隔符 Content-Disposition: form-data; name="username" 空行 123456 */ [fileData appendData:[[NSString stringWithFormat:@"--%@",Kboundary] dataUsingEncoding:NSUTF8StringEncoding]]; [fileData appendData:KNewLine]; [fileData appendData:[@"Content-Disposition: form-data; name=\"username\"" dataUsingEncoding:NSUTF8StringEncoding]]; [fileData appendData:KNewLine]; [fileData appendData:KNewLine]; [fileData appendData:[@"123456" dataUsingEncoding:NSUTF8StringEncoding]]; [fileData appendData:KNewLine]; //5.3 結尾標識 /* --分隔符-- */ [fileData appendData:[[NSString stringWithFormat:@"--%@--",Kboundary] dataUsingEncoding:NSUTF8StringEncoding]]; return fileData; } @end
###2.AFN文件上傳
```objc
1.文件上傳拼接數據的第一種方式
[formData appendPartWithFileData:data name:@"file" fileName:@"xxoo.png" mimeType:@"application/octet-stream"];
2.文件上傳拼接數據的第二種方式
[formData appendPartWithFileURL:fileUrl name:@"file" fileName:@"xx.png" mimeType:@"application/octet-stream" error:nil];
3.文件上傳拼接數據的第三種方式
[formData appendPartWithFileURL:fileUrl name:@"file" error:nil];
4.【注】在資料中已經提供了一個用於文件上傳的分類。
/*文件上傳相關的代碼如下*/
-(void)upload1
{
//1.創建會話管理者
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
//2.處理參數(非文件參數)
NSDictionary *dict = @{
@"username":@"123"
};
//3.發送請求上傳文件
/*
第一個參數:請求路徑(NSString類型)
第二個參數:非文件參數,以字典的方式傳遞
第三個參數:constructingBodyWithBlock 在該回調中拼接文件參數
第四個參數:progress 進度回調
uploadProgress.completedUnitCount:已經上傳的數據大小
uploadProgress.totalUnitCount:數據的總大小
第五個參數:success 請求成功的回調
task:上傳Task
responseObject:服務器返回的響應體信息(已經以JSON的方式轉換為OC對象)
第六個參數:failure 請求失敗的回調
task:上傳Task
error:錯誤信息
*/
[manager POST:@"http://120.25.226.186:32812/upload" parameters:dict constructingBodyWithBlock:^(id<AFMultipartFormData> _Nonnull formData) {
UIImage *image = [UIImage imageNamed:@"Snip20160117_1"];
NSData *imageData = UIImagePNGRepresentation(image);
//在該block中拼接要上傳的文件參數
/*
第一個參數:要上傳的文件二進制數據
第二個參數:文件參數對應的參數名稱,此處為file是該台服務器規定的(通常會在接口文檔中提供)
第三個參數:該文件上傳到服務后以什么名稱保存
第四個參數:該文件的MIMeType類型
*/
[formData appendPartWithFileData:imageData name:@"file" fileName:@"123.png" mimeType:@"image/png"];
} progress:^(NSProgress * _Nonnull uploadProgress) {
NSLog(@"%f",1.0 * uploadProgress.completedUnitCount / uploadProgress.totalUnitCount);
} success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
NSLog(@"請求成功----%@",responseObject);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
NSLog(@"請求失敗----%@",error);
}];
}
-(void)upload2
{
//1.創建會話管理者
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
//2.處理參數(非文件參數)
NSDictionary *dict = @{
@"username":@"123"
};
//3.發送請求上傳文件
/*
第一個參數:請求路徑(NSString類型)
第二個參數:非文件參數,以字典的方式傳遞
第三個參數:constructingBodyWithBlock 在該回調中拼接文件參數
第四個參數:progress 進度回調
uploadProgress.completedUnitCount:已經上傳的數據大小
uploadProgress.totalUnitCount:數據的總大小
第五個參數:success 請求成功的回調
task:上傳Task
responseObject:服務器返回的響應體信息(已經以JSON的方式轉換為OC對象)
第六個參數:failure 請求失敗的回調
task:上傳Task
error:錯誤信息
*/
[manager POST:@"http://120.25.226.186:32812/upload" parameters:dict constructingBodyWithBlock:^(id<AFMultipartFormData> _Nonnull formData) {
NSURL *fileUrl = [NSURL fileURLWithPath:@"/Users/文頂頂/Desktop/Snip20160117_1.png"];
//在該block中拼接要上傳的文件參數
//第一種拼接方法
/*
第一個參數:要上傳的文件的URL路徑
第二個參數:文件參數對應的參數名稱,此處為file是該台服務器規定的(通常會在接口文檔中提供)
第三個參數:該文件上傳到服務后以什么名稱保存
第四個參數:該文件的MIMeType類型
第五個參數:錯誤信息,傳地址
*/
//[formData appendPartWithFileURL:fileUrl name:@"file" fileName:@"1234.png" mimeType:@"image/png" error:nil];
//第二種拼接方法:簡寫方法
/*
第一個參數:要上傳的文件的URL路徑
第二個參數:文件參數對應的參數名稱,此處為file
第三個參數:錯誤信息
說明:AFN內部自動獲得路徑URL地址的最后一個節點作為文件的名稱,內部調用C語言的API獲得文件的類型
*/
[formData appendPartWithFileURL:fileUrl name:@"file" error:nil];
} progress:^(NSProgress * _Nonnull uploadProgress) {
NSLog(@"%f",1.0 * uploadProgress.completedUnitCount / uploadProgress.totalUnitCount);
} success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
NSLog(@"請求成功----%@",responseObject);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
NSLog(@"請求失敗----%@",error);
}];
}
```