在開發過程中,經常性的要把圖片資源發送給服務器, AFNetworking 基本是網絡處理的基本框架,在最新 AFN 3.0.0 以後, AFN 已經摒棄了對 NSURLConnection 的支持,全力使用 NSURLSession 來處理網絡請求.但一些老一點的項目當中, AFN 可能還比較古老,老框架和最新的 AFN 3.1.0 在網絡請求上面有什麼區別呢? 就以圖片上傳爲例:
(1) AFN2.0 以前的來上傳圖片:
1. 設置請求頭
+ (AFHTTPClient *)getNsurlRequestPath:(NSString *)path params:(NSDictionary *)params method:(NSString *)method
{
AFHTTPClient *client = [AFHTTPClient clientWithBaseURL:[NSURL URLWithString:shareTool.baseUrl]];
//設置header
[client setDefaultHeader:@"xxx" value:xxx];
[client setDefaultHeader:@"xxx" value:xxx];
// 或取當前時間戳
NSString *timeInterval = [NSString stringWithFormat:@"%f",[[NSDate date] timeIntervalSince1970]];
[client setDefaultHeader:@"r" value:timeInterval];
// EncryPtionTool MD5 加密處理類
[client setAuthorizationHeaderWithUsername:kAppName password:[EncryPtionTool GetMd5String:[NSString stringWithFormat:@"xxx%@%@",timeInterval,kKey]]];
return client;
}
+(void)upLoadImageSuccess:(void (^)())success failure:(void (^)(NSError *))failure
{
NSString* path=@"xxxxxxxxxxxxx";
NSMutableDictionary* param=[NSMutableDictionary dictionary];
param[@"xxx"]=@"";
AFHTTPClient* client=[self getNsurlRequestPath:path params:param method:@"post"];
// 上傳圖片
NSURLRequest* request= [client multipartFormRequestWithMethod:@"post" path:path parameters:param constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
// 要上傳的圖片 以單張圖片爲例
UIImage *image = [UIImage imageNamed:@"image_test"];
NSData *data = UIImageJPEGRepresentation(image, 0.7);
while (data.length > 1024 * 500) { // 壓縮小於 500 k
image = [[UIImage alloc] initWithData:data];
data = UIImageJPEGRepresentation(image, 0.07);
}
// 在網絡開發中,上傳文件時,是文件不允許被覆蓋,文件重名
// 要解決此問題,
// 可以在上傳時使用當前的系統事件作爲文件名
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
// 設置時間格式
formatter.dateFormat = @"yyyyMMddHHmmss";
NSString *str = [formatter stringFromDate:[NSDate date]];
NSString *fileName = [NSString stringWithFormat:@"%@.png", str];
[formData appendPartWithFileData:data name:@"file" fileName:fileName mimeType:@"image/png"];
}];
AFHTTPRequestOperation* operation=[[AFHTTPRequestOperation alloc] initWithRequest:request];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
NSDictionary *JSON = [NSJSONSerialization JSONObjectWithData:operation.responseData options:NSJSONReadingMutableContainers error:nil];
if ([JSON[@"code"] integerValue] != 0) {
NSError* error=[[NSError alloc] initWithDomain:JSON[@"msg"] code:[JSON[@"code"] integerValue] userInfo:@{@"msg" : JSON[@"msg"]}];
if (failure) {
failure(error);
return ;
}
}
if (success) {
success();
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
if (failure) {
failure(error);
}
}];
/**
@param bytesWritten 每次寫進的字節數
@param totalBytesWritten 總共寫進的字節數
@param totalBytesExpectedToWrite 期望寫進的字節數
*/
__block NSString* total=nil;
__block NSString* totalExpect=nil;
[operation setUploadProgressBlock:^(NSUInteger bytesWritten, long long totalBytesWritten, long long totalBytesExpectedToWrite) {
total=[NSString stringWithFormat:@"%lld",totalBytesWritten ];
totalExpect=[NSString stringWithFormat:@"%lld",totalBytesExpectedToWrite ];
// 監聽上傳進度
CGFloat progress =[total floatValue] / [totalExpect floatValue] ;
NSLog(@"---%f",progress);
NSLog(@"Sent %d 總共 %lld of %lld bytes",bytesWritten, totalBytesWritten, totalBytesExpectedToWrite);
}];
// 執行操作
[client.operationQueue addOperation:operation];
}
(2) AFN 3.1.0 上傳圖片
1.設置請求頭
+(AFHTTPSessionManager*) sessionManager
{
AFHTTPSessionManager* sessinManager=[[AFHTTPSessionManager alloc] initWithBaseURL:[NSURLURLWithString:kBaseURL]];
sessinManager.responseSerializer=[AFJSONResponseSerializer serializer];
// 設置請求頭
[sessinManager.requestSerializer setValue:xxx forHTTPHeaderField:@"xxx"];
[sessinManager.requestSerializer setValue:xxx forHTTPHeaderField:@"xxxx"];
// 時間戳
NSString *timeInterval = [NSString stringWithFormat:@"%f",[[NSDate date] timeIntervalSince1970]];
[sessinManager.requestSerializer setValue:timeInterval forHTTPHeaderField:@"r"];
NSString* passWord= [EncryPtionTool GetMd5String:[NSStringstringWithFormat:@"xxx%@%@",timeInterval,kKey]];
[sessinManager.requestSerializer setAuthorizationHeaderFieldWithUsername:kAppName password:passWord];
sessinManager.requestSerializer.timeoutInterval=5.0;
return sessinManager;
}
2.發送請求
+(void)downUpImageSuccess:(void (^)(NSDictionary *))success failure:(void (^)(NSError *))failure
{
AFHTTPSessionManager* sessionManager= [self sessionManager];
NSString* path=@"xxxxxx";
NSMutableDictionary* param=[NSMutableDictionary dictionary];
param[@"xxxx"]=@"";
[sessionManager POST:path parameters:param constructingBodyWithBlock:^(id<AFMultipartFormData> _Nonnull formData) {
/***** 在這裏直接添加上傳的圖片 *****/
UIImage *image = [UIImage imageNamed:@"image_test"];
NSData *data = UIImagePNGRepresentation(image);
// 在網絡開發中,上傳文件時,是文件不允許被覆蓋,文件重名
// 要解決此問題,
// 可以在上傳時使用當前的系統事件作爲文件名
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
// 設置時間格式
formatter.dateFormat = @"yyyyMMddHHmmss";
NSString *str = [formatter stringFromDate:[NSDate date]];
NSString *fileName = [NSString stringWithFormat:@"%@.png", str];
[formData appendPartWithFileData:data name:@"file" fileName:fileName mimeType:@"image/png"];
} progress:^(NSProgress * _Nonnull uploadProgress) {
// 獲取上傳進度
} success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable JSON) {
if ([JSON[@"code"] integerValue] != 0) { // 返回 code 值不爲 0
NSError* error=[[NSError alloc] initWithDomain:JSON[@"msg"] code:[JSON[@"code"] integerValue] userInfo:@{@"msg" : JSON[@"msg"]}];
failure(error);
return ;
}
NSLog(@"上傳成功");
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
NSLog(@"上傳失敗");
failure(error);
}];
}
由上面可以看到, AFN 3.1.0 對 NSURLSession 封裝,除了性能更優,相對以前,代碼更集中,更易處理.