在ios开发中,http请求是必不可少的部分,当然苹果自带的http请求可能有些繁琐,于是就诞生了很多的第三方类库,其中afn不可不说是一个不错的选择。有时候,afn更新的时候,可能会修改一些方法的名字,或者逻辑,那么对于开发者来说,不更新afn,直接用原来的还好说,如果一旦我们也用新的afn,那么我们就不得不一个一个页面的去修改里面的方法了,很痛苦。所以如果我们对第三方类库afn再进行一次封装就好了。下次,afn更新时,我们只需要修改一下我们封装的方法就可以了。
首先,我们先看一下afn最新的两个post请求和一个get请求方法:
//get请求
- (AFHTTPRequestOperation *)GET:(NSString *)URLString
parameters:(id)parameters
success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success
failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure
{
AFHTTPRequestOperation *operation = [self HTTPRequestOperationWithHTTPMethod:@"GET" URLString:URLString parameters:parameters success:success failure:failure];
[self.operationQueue addOperation:operation];
return operation;
}
//post请求,不包含上传文件等东西
- (AFHTTPRequestOperation *)POST:(NSString *)URLString
parameters:(id)parameters
success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success
failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure
{
AFHTTPRequestOperation *operation = [self HTTPRequestOperationWithHTTPMethod:@"POST" URLString:URLString parameters:parameters success:success failure:failure];
[self.operationQueue addOperation:operation];
return operation;
}
//post请求,可以上传文件等东西
- (AFHTTPRequestOperation *)POST:(NSString *)URLString
parameters:(id)parameters
constructingBodyWithBlock:(void (^)(id <AFMultipartFormData> formData))block
success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success
failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure
{
NSError *serializationError = nil;
NSMutableURLRequest *request = [self.requestSerializer multipartFormRequestWithMethod:@"POST" URLString:[[NSURL URLWithString:URLString relativeToURL:self.baseURL] absoluteString] parameters:parameters constructingBodyWithBlock:block error:&serializationError];
if (serializationError) {
if (failure) {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wgnu"
dispatch_async(self.completionQueue ?: dispatch_get_main_queue(), ^{
failure(nil, serializationError);
});
#pragma clang diagnostic pop
}
return nil;
}
AFHTTPRequestOperation *operation = [self HTTPRequestOperationWithRequest:request success:success failure:failure];
[self.operationQueue addOperation:operation];
return operation;
}
然后我们看一下如何使用这三个方法
//get请求,无请求参数的情况下
//创建请求管理类
AFHTTPRequestOperationManager*mager=[AFHTTPRequestOperationManager manager];
//mager.responseSerializer = [AFJSONResponseSerializer serializer];//申明返回的结果是json类型
//mager.requestSerializer=[AFJSONRequestSerializer serializer];//申明请求的数据是json类型
//[mager.requestSerializer setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];//往头部添加一些信息
//[mager.requestSerializer setValue:token forHTTPHeaderField:@"token"];//往头部添加一些信息
NSString *strurl=@"服务器给的地址";
[mager GET:strurl parameters:nil success:^(AFHTTPRequestOperation * operation, id responseObject) {
//请求数据成功处理,返回结果在responseObject里面
NSLog(@"查看一下responseObject的类型-----%@",[responseObject class]);
NSLog(@"查看一下responseObject的内容-----%@",responseObject);
} failure:^(AFHTTPRequestOperation * operation, NSError * error) {
//请求数据失败处理
}];
//post请求 有请求参数的情况下
NSMutableDictionary *parameters=[NSMutableDictionary dictionary];
parameters[@"phone_number"]=self.phonetextfield.text;
parameters[@"validate_number"]=self.checktextfield.text;
AFHTTPRequestOperationManager*mager=[AFHTTPRequestOperationManager manager];
NSString *strurl=@"服务器给的地址";
[mager POST:strurl parameters:parameters success:^(AFHTTPRequestOperation * operation, id responseObject) {
//请求数据成功处理
} failure:^(AFHTTPRequestOperation * operation, NSError * error) {
//请求数据失败处理
}];
//post请求,无参数传入图片情况下
AFHTTPRequestOperationManager*mager=[AFHTTPRequestOperationManager manager];
[mager POST:url parameters:parameters constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
UIImageView *imageview1=[[UIImageView alloc]initWithImage:[UIImage imageNamed:@"tupian1.png"]];
UIImageView *imageview2=[[UIImageView alloc]initWithImage:[UIImage imageNamed:@"tupian2.png"]];
NSData *data1=UIImageJPEGRepresentation(imageview1.image, 1.0);//压缩图片比例1:1。
[formData appendPartWithFileData:data1 name:@"pic" fileName:@"" mimeType:@"image/jpeg"];
NSData *data2=UIImageJPEGRepresentation(imageview2.image, 0.5);//压缩图片比例1:2。
[formData appendPartWithFileData:data2 name:@"pic" fileName:@"" mimeType:@"image/jpeg"];
} success:^(AFHTTPRequestOperation *operation, id responseObject) {
//请求数据成功处理
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
//请求数据失败处理
}];
接下来,我们开始对这三个方法进行封装
首先创建一个继承uiview的类。导入afn头文件
然后依照afn的方法名,我们也创建一个方法
#import <UIKit/UIKit.h>
@interface JSCHttpTool : UIView
+(void)Post:(NSString *)url parameters:(NSDictionary *)parameters success:(void(^)(id json))success failure:(void(^)(NSError *error))failure;
@end
实现里面
#import "JSCHttpTool.h"
#import "AFNetworking.h"
@implementation JSCHttpTool
//实现里面一定要手打这个方法,根据提示敲出来。因为这个里面和定义里面不完全一样。 定义里面有个id josn 在实现里面,默认是没有的
+(void)POST:(NSString *)url parameters:(NSDictionary *)parameters success:(void (^)(id))success failure:(void (^)(NSError *))failure
{
AFHTTPRequestOperationManager*mager=[AFHTTPRequestOperationManager manager];
[mager POST:url parameters:parameters success:^(AFHTTPRequestOperation * operation, id responseObject) {
if (success) {
success(responseObject);
}
} failure:^(AFHTTPRequestOperation * operation, NSError * error) {
if (failure) {
failure(error);
}
}];
}
@end
解释一下,这个方法中的第一个success是和这个方法一起组合的方法名中的一部分,第二个success则是block方法名
(void(^)(id json))success
这个代表,定义一个block,方法名是success,void是没有返回值,而传入参数是id类型的 josn是参数名
ps:block不会的同学请自行脑补
这里我们调用afn,然后
if (success) {
success(responseObject);
}
这句代码,表示,如果使用页面中success这个block存在,则回使用页面中的success block方法,传入afn返回的数据responseObject。
ok,我们在使用页面先试用一下,在使用页面导入我们的JSCHttpTool头文件
NSString *strurl=@"服务器给的地址";
[JSCHttpTool Post:@"" parameters:parameters success:^(id json) {
//请求数据成功处理,返回结果在responseObject里面
NSLog(@"查看一下responseObject的类型-----%@",[responseObject class]);
NSLog(@"查看一下responseObject的内容-----%@",responseObject);
} failure:^(NSError *error) {
//请求数据失败处理
}];
ok了,以后,afn如果更改这个方法了,我们只需要更改我们的JSCHttpTool就可以了。
接下来,依次,我们把别的两个方法也封装进来。
+(void)GET:(NSString *)url parameters:(NSDictionary *)parameters success:(void (^)(id))success failure:(void (^)(NSError *))failure
{
AFHTTPRequestOperationManager *mager =[AFHTTPRequestOperationManager manager];
[mager GET:url parameters:parameters success:^(AFHTTPRequestOperation *operation, id responseObject) {
if (success) {
success(responseObject);
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
if (failure) {
failure(error);
}
}];
}
+(void)POST:(NSString *)url parameters:(id)parameters constructingBodyWithBlock:(NSArray *(^)(void))block success:(void (^)(id))success failure:(void (^)(NSError *))failure
{
AFHTTPRequestOperationManager *mager =[AFHTTPRequestOperationManager manager];
[mager POST:url parameters:parameters constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
if (block) {
NSArray *dataarray= block();
for (NSData *data in dataarray) {
[formData appendPartWithFileData:data name:@"pic" fileName:@"" mimeType:@"image/jpeg"];
}
}
} success:^(AFHTTPRequestOperation *operation, id responseObject) {
if (success) {
success(responseObject);
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
if (failure) {
failure(error);
}
}];
}
其中,如果不是很理解的人,我再说一下我的这个post请求在有传入文件的这个情况下使用方法:
NSString *strurl=@"服务器给的地址";
[JSCttpTool Post:strurl parameters:parameters constructingBodyWithBlock:^NSArray *{
NSMutableArray *dataarray=[NSMutableArray array];
UIImageView *imageview1=[[UIImageView alloc]initWithImage:[UIImage imageNamed:@"tupian1.png"]];
UIImageView *imageview2=[[UIImageView alloc]initWithImage:[UIImage imageNamed:@"tupian2.png"]];
NSData *data1=UIImageJPEGRepresentation(imageview1.image, 1.0);
[dataarray addObject:data1];
NSData *data2=UIImageJPEGRepresentation(imageview2.image, 0.5);
[dataarray addObject:data2];
return dataarray;
} success:^(id json) {
//请求数据成功处理
} failure:^(NSError *error) {
//请求数据成功处理
}];
OK!搞定!