AFNetworking之关于GET、POST、PUT、DELETE封装之旅

前言 

这套网络请求其实是两年前封装好的,不过在多个项目中一直在用它,故此将此分享出来

问题来源

每次加载不同方式请求都要写一遍请求接口数据代码,虽说可以直接粘贴复制,不过审美观实在太差,如下

 
    //获得请求管理者
    AFHTTPSessionManager *mgr = [AFHTTPSessionManager manager];
    //请求超时时间
    mgr.requestSerializer.timeoutInterval = 18;
    //加上此代码就可以了 声明了传过去的参数是json格式
    mgr.requestSerializer = [AFJSONRequestSerializer serializer];
    //#ifdef ContentType
    mgr.responseSerializer.acceptableContentTypes =  [NSSet setWithObjects:@"text/plain", @"application/json", @"text/json", @"text/javascript",@"text/html", nil];
    mgr.responseSerializer = [AFHTTPResponseSerializer serializer];
     NSString* url = @"请求url";
     NSDictionary *params = @{};
    [mgr GET:url parameters:params progress:^(NSProgress * _Nonnull downloadProgress) {
        } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
         
        //一顿骚操作
 
        } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
          
       //辣眼睛操作 
        }];

如果别的接口是post请求,并且请求url不同,请求入参也不同,那就只能在复制一份这样的代码,只是把不同的地方换掉即可,反正粘贴复制嘛(这重复很多遍这样操作,显得很low) 

解决思路

封装的核心思想简单点概括就是去重,将重复的作为参数,其余不重复的共用即可

整理好思路,那可以确定下来的就是请求方式、url、入参作为封装方法的参数,其余AFN相关代码实现为共用代码

  1. 创建一个类继承NSObject,我把它取名为HttpTool,按照刚刚分析创建封装好的方法,如下
  2. 实现逻辑,因为重点是不同的请求方式,所以需要定义枚举区别
typedef NS_ENUM(NSUInteger,RequestMethodType){
    RequestGet = 1,
    RequestPost = 2,
    RequestPut = 3,
    RequestDelete = 4,
};

@interface HttpTool : NSObject
/**
 *  发送一个请求 
 *
 *  @param type   请求方法
 *  @param url          请求路径
 *  @param params       请求参数
 *  @param succes  请求成功后的回调(请将请求成功后想做的事情写到这个block中)
 *  @param failure 请求失败后的回调(请将请求失败后想做的事情写到这个block中)
 */
+(void)requestMethod:(RequestMethodType)type
                 url:(NSString *)url
              params:(NSDictionary *)params
              succes:(void (^)(id response))succes
             failure:(void (^)(NSError *err))failure;

为什么多了两个block,因为AFN请求需要接受成功和失败回调,我们需要定义接受AFN请求结果作为回调

实现

+(void)requestMethod:(RequestMethodType)type
                 url:(NSString *)url
              params:(NSDictionary *)params
              succes:(void (^)(id response))succes
             failure:(void (^)(NSError *err))failure{
    
    //获得请求管理者
    AFHTTPSessionManager *mgr = [AFHTTPSessionManager manager];
    //请求超时时间
    mgr.requestSerializer.timeoutInterval = 18;
    //加上此代码就可以了 声明了传过去的参数是json格式
    mgr.requestSerializer = [AFJSONRequestSerializer serializer];
    //#ifdef ContentType
    mgr.responseSerializer.acceptableContentTypes =  [NSSet setWithObjects:@"text/plain", @"application/json", @"text/json", @"text/javascript",@"text/html", nil];
    
    NSString * token =  [[NSUserDefaults standardUserDefaults] objectForKey:@"token"];
    if (token) {
        
       [mgr.requestSerializer setValue:token forHTTPHeaderField:@"token"];
    }
    url = [url stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
    
    switch (type) {
        case RequestGet:{
        mgr.responseSerializer = [AFHTTPResponseSerializer serializer];
        [mgr GET:url parameters:params progress:^(NSProgress * _Nonnull downloadProgress) {
        } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
            
            if (succes){
                succes(responseObject);
            }
        } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
            if (failure) {
                failure(error);
            }
        }];
        }break;
            
        case RequestPost:{
        [mgr POST:url parameters:params progress:^(NSProgress * _Nonnull uploadProgress) {
            
        } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
            if (succes) {
                NSHTTPURLResponse *response = (NSHTTPURLResponse *)task.response;
                NSDictionary *allHeaders = response.allHeaderFields;
               
                if(allHeaders[@"token"]){
                  [[NSUserDefaults standardUserDefaults] setObject:allHeaders[@"token"] forKey:@"token"];
                   NSLog(@"%@ allHeaders",allHeaders[@"token"]);
                }
                NSLog(@"%@ allHeaders",allHeaders);
                succes(responseObject);
            }
            
        } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
            
            if (failure) {
                failure(error);
            }
        }];
        }break;
            
            
        case RequestPut:{
        [mgr PUT:url parameters:params success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
            if (succes) {
                succes(responseObject);
            }
        } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
            
            if (failure) {
                failure(error);
            }
        }];
        }break;
            
        case RequestDelete:{
        [mgr DELETE:url parameters:params success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
            if (succes) {
                succes(responseObject);
            }
            
        } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
            
            if (failure) {
                failure(error);
            }
        }];
        }break;
        default:
            break;
    }
}

至此就完事了

举例

在HttpTool头文件定义一个方法,假如是A接口的实现方法,因为我们需要成功和失败的回调,所以入参可以确认有这两个,还有一个就是接口入参(字典类型),url我建议不作为入参,原因后续讲解,如下

//版本更新
+(void)VersionUpdate:(NSDictionary *)parameter
             success:(void (^)(id response))success
             failure:(void (^)(NSError *err))failure;

实现

//版本更新
+(void)VersionUpdate:(NSDictionary *)parameter
             success:(void (^)(id response))success
             failure:(void (^)(NSError *err))failure{
    
     NSString * url = [NSString stringWithFormat:@"%@/other/app_version",YLZDomain(Domain)];
     [HttpTool requestMethod:RequestPost url:url params:parameter succes:success failure:failure];
}

YLZDomain(Domain)是定义的宏,因为我都知道有正式环境和测试环境(有些公司还有仿真环境),环境的区别也就是域名不同,所以直接两者之间切换即可。

注:url不做入参我考虑原因一为了让方法看上去简单明了,二是接口也具有封装性(YLZDomain(Domain)也算一种封装),三是不暴露接口明细

猜你喜欢

转载自blog.csdn.net/JSON_6/article/details/81162957
今日推荐