程序员

基于AFNetworking的网络请求管理-YRequestMa

2018-02-07  本文已影响261人  Andys

GitHub地址:https://github.com/Andy888888/YRequestManager

Logo

YRequestManager

Base AFNetworking Core Network Request Framework
Description

简介

基于AFNetworking作为网络请求核心,封装的网络请求管理工具。通过Api类作为请求配置描述,Manager做为管理发送方来发出请求;默认提供了三个拦截器:NetworkProtocalInterceptor(错误后处理状态码,网络层),ReqLogInterceptor(发起请求前打印日志),RespSucInterceptor(响应成功后做数据转实体,可用第三方转换工具);RequestManager提供了默认实例化方法:defaultMamanger,会把默认的三个拦截器加入进来,如果项目中不想用这三个拦截器,或不满足需求,可继承他们的父类自己重写,当然,RequestManager的实例化方法也要改为:initManagerWithYDelegate。

pod 使用

pod search YRequestManager
pod 'YRequestManager'

结构概览

1.ApiDelegate
2.AbsApi
3.BaseApi
4.BaseServiceManager
5.RequestManager

详解

1.ApiDelegate Protocal协议

该协议规范了凡遵守该协议的Api对象都拥有getReqUrl,getReqHeader,getReqBody,getRequestMethod,getTimeOut方法。这种设计方式借鉴了Java,C#语法的Interface接口的设计思想。

2.AbsApi abstract抽象类

请求抽象类,规范了继承自AbsApi需要实现的方法。这种设计方式借鉴了Java,C#语法的abstract抽象类的设计思想。

3.BaseApi 请求Api基类

请求基类,继承自AbsApi,且遵守了ApiDelegate协议。
内部实现了ApiDelegate协议的方法,大家使用时直接继承BaseApi。而如果BaseApi如果不符合你的口味,你可以来自定义一个继承AbsApi又遵守BaseApiDelegate协议的对象

4.BaseServiceManager

用来使用AFNetWorking发送请求,只是个管理者,本身并不具备发送请求能力;目前依赖于AFNetWorking来发送网络请求;在内部封装了一些默认创建AFHTTPSessionManager的方法。

/// 使用block方式发送数据请求;api:发送参数,sucBlock:成功回调,failBlock:失败回调
- (void)request:(AbsApi<ApiDelegate>*)api
       sucBlock:(RespSucBlock)sucBlock
      failBlock:(RespFailBlock)failBlock;

该方法使用Block回调来发送请求,api参数为继承AbsApi抽象类,且遵守ApiDelegate协议的对象,(PS:BaseApi就符合该约束,凡继承BaseApi的对象都符合该参数约束) BaseServiceManager内部通过api对象配置来发送请求。sucBlockfailBlock为请求成功/失败回调。

5.RequestManager

继承自BaseServiceManager;设计此Manager主要目的是,后期不采用AFNetWorking时,可在本类的发送方法sendRequest...中切换其他第三方请求框架即可,而不需要项目中到处修改AFNetWorking请求为其他方式请求,同时担任着控制第三方请求的角色;因此,即使看不惯本类,也不要修改;另外,本类增加了Protocal回调数据方式请求。

/// ResponseDelegate 数据响应回调协议
@property (nonatomic,assign) id<YResponseDelegate> ydelegate;

+ (id)initManagerWithDelegate:(id<ResponseDelegate>)delegate;
/// 发送数据请求,参数为继承AbsApi抽象类,且遵守BaseApiDelegate协议 的对象
- (void)sendRequest:(AbsApi<ApiDelegate>*)api;

我们可以直接使用initManagerWithYDelegate:或者defaultManager方法来初始化RequestManager对象,将数据回调协议delegate传入。

使用request:方法来发送请求,同父类一致,api参数为继承AbsApi抽象类,且遵守BaseApiDelegate协议的对象。而上述BaseApi就符合这一点,而BaseApi如果不符合你的口味,你可以来自定义一个继承AbsApi又遵守BaseApiDelegate协议的对象。








使用方式

1.Api配置类

// 导入
#import "BaseApi.h"

// PokemonBaseApi继承自BaseApi
@implementation PokemonBaseApi

- (NSString *)getRootUrl
{
    return @"https://pokevision.com/";
}

- (int)getTimeOut
{
    return 30;
}

- (int)getRequestMethod
{
    return RequestMethodGET;
}

- (NSString *)checkRespData:(id)data
{
    PokemonBaseDo *pokemon = data;
    NSString *status = pokemon.status;
    if(![status isEqualToString:@"success"]){
        return @"查询失败";
    }
    return nil;
}
@end
// PokemonPositionApi继承自PokemonBaseApi
@implementation PokemonPositionApi

- (NSString *)getPath
{
    return @"map/data/34.00/-118.5";
}

- (NSDictionary *)getBody
{
    return @{@"User":_user,@"Pwd":_pwd};
}

- (Class)getRespClass
{
    return [PkPositionDo class];
}

- (int)getRequestMethod
{
    return RequestMethodGET;
}

@end


// 初始化要请求的接口配置
PokemonPositionApi *api = [[PokemonPositionApi alloc]init];
// 设置配置:请求body参数
api.user = @"andy";
api.pwd = @"pwd";






2.RequestManager请求


#import "RequestManager.h"

// 初始化请求管理类
RequestManager *reqManager = [RequestManager defaultManager:self];
// 添加响应成功后,数据转换实体方式拦截器
[reqManager setInterceptorForSuc:[DataConvertInterceptor new]];
// 发送请求:Protocol方式接收数据
[reqManager request:api];

// 发送请求:Block方式接收数据
[reqManager request:api sucBlock:^(CentaResponse *result) {
        if(result.suc){
            PkPositionDo *position = result.data;
            NSString *status = position.status;
            NSLog(status);
        }else{
            NSLog(result.msg);
        }
    } failBlock:^(CentaResponse *error) {
        NSLog(error.msg);
    }];



@implementation DataConvertInterceptor

- (CentaResponse *)convertData:(id)task andRespData:(id)respData andApi:(AbsApi<ApiDelegate> *)api
{
    CentaResponse *resp =  [super convertData:task andRespData:respData andApi:api];
    NSDictionary *dic = resp.data;
    
    // 使用yymodel转换成目标实体
    Class cls = api.getRespClass;
    resp.data = [cls yy_modelWithDictionary:dic];
    
    return resp;
}
@end

上一篇下一篇

猜你喜欢

热点阅读