YRequestManager
基于 AFNetworking 核心网络请求框架
简介
基于 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 协议
该协议定义了所有遵守该协议的Api对象都必须实现的getReqUrl
、getReqHeader
、getReqBody
、getRequestMethod
、getTimeOut
方法。这种设计思想借鉴了Java、C#语法的Interface接口。
getReqUrl
用来配置请求地址Url,实现者需返回一个NSString
对象。getReqHeader
用来配置请求Header,实现者需返回一个NSDictionary
对象。getReqBody
用来配置请求Body,实现者需返回一个NSDictionary
对象。getRequestMethod
用来配置该请求方法,使用枚举RequestMethod来区分,可返回RequestMethodPOST
(POST请求)、RequestMethodGET
(GET请求)、RequestMethodPUT
(PUT请求)、RequestMethodDELETE
(DELETE请求)。getTimeOut
用来配置请求超时时间。
2.AbsApi 抽象类
定义了继承自AbsApi类需要实现的方法。这种设计思想借鉴了Java、C#语法的abstract抽象类。
getRootUrl
请求域名url。默认为nil,实现者必须实现。getPath
请求Url的后半部分。默认为nil,实现者必须实现。getBaseHeader
基本header。默认为nil,若有每个请求必填的header字段,请实现此方法。getHeader
除基本header以外的请求header。默认为nil,实现者必须实现。getBaseBody
基本body。默认为nil,若有每个请求必填的body字段,请实现此方法。getBody
除基本body以外的请求body。默认为nil,实现者必须实现。getRespClass
用来指定该请求返回的数据实体Class,实现者重写该方法需返回一个Class类型[实体类],将返回的数据转换为指定数据实体对象。在同一页面中发起n个不同api请求后,返回的数据可以通过class来识别。
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对象配置发送请求。sucBlock
、failBlock
为请求成功/失败回调。
5.RequestManager
继承自BaseServiceManager;设计此Manager的主要目的是,在后期不再使用AFNetWorking时,可以在本类的sendRequest...发送方法中切换其他第三方请求框架,而不需要在项目中到处修改AFNetWorking请求为其他方式请求,同时担任控制第三方请求的角色;因此,即使对本类有意见,也不要修改;另外,本类增加了通过Protocol回调数据方式的请求。
/// 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配置类
- 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
- Api配置类的实例化
// 初始化要请求的接口配置
PokemonPositionApi *api = [[PokemonPositionApi alloc]init];
// 设置配置:请求body参数
api.user = @"andy";
api.pwd = @"pwd";
2.RequestManager请求
- 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);
}];
-
DataConvertInterceptor(继承自InterceptorForRespSuc)
DataConvertInterceptor不是框架自带的功能,因为框架不应该限制业务层使用什么进行数据转换,
因此,这个过程是开放的,用户可以自行决定。(示例代码中是使用yyModel转换)
@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