移步Github:YRequestManager
YRequestManager
Base AFNetworking Core Network Request Framework
簡介
基于AFNetworking作為網(wǎng)絡(luò)請求核心休雌,封裝的網(wǎng)絡(luò)請求管理工具命咐。通過Api類作為請求配置描述,Manager做為管理發(fā)送方來發(fā)出請求勃痴;默認(rèn)提供了三個攔截器:NetworkProtocalInterceptor(錯誤后處理狀態(tài)碼斗塘,網(wǎng)絡(luò)層),ReqLogInterceptor(發(fā)起請求前打印日志),RespSucInterceptor(響應(yīng)成功后做數(shù)據(jù)轉(zhuǎn)實體媚值,可用第三方轉(zhuǎn)換工具);RequestManager提供了默認(rèn)實例化方法:defaultMamanger护糖,會把默認(rèn)的三個攔截器加入進(jìn)來褥芒,如果項目中不想用這三個攔截器,或不滿足需求嫡良,可繼承他們的父類自己重寫锰扶,當(dāng)然,RequestManager的實例化方法也要改為:initManagerWithYDelegate寝受。
pod 使用
pod search YRequestManager
pod 'YRequestManager'
結(jié)構(gòu)概覽
1.ApiDelegate
2.AbsApi
3.BaseApi
4.BaseServiceManager
5.RequestManager
詳解
1.ApiDelegate Protocal協(xié)議
該協(xié)議規(guī)范了凡遵守該協(xié)議的Api對象都擁有getReqUrl
,getReqHeader
,getReqBody
,getRequestMethod
,getTimeOut
方法坷牛。這種設(shè)計方式借鑒了Java,C#語法的Interface接口的設(shè)計思想很澄。
-
getReqUrl
用來配置請求地址Url京闰,遵守者實現(xiàn)該方法需返回一個NSString
對象颜及。
-
getReqHeader
用來配置請求Header,遵守者實現(xiàn)該方法需返回一個NSDictionary
對象蹂楣。
-
getReqBody
用來配置請求Body俏站,遵守者實現(xiàn)該方法需返回一個NSDictionary
對象。
-
getRequestMethod
用來配置該請求方式痊土,用enum枚舉RequestMethod來區(qū)分肄扎,可返回RequestMethodPOST
(Post請求)、RequestMethodGET
(Get請求)RequestMethodPUT
(Put請求)赁酝、RequestMethodDELETE
(Delete請求)犯祠。
-
getTimeOut
用來配置請求超時時間。
2.AbsApi abstract抽象類
請求抽象類赞哗,規(guī)范了繼承自AbsApi需要實現(xiàn)的方法雷则。這種設(shè)計方式借鑒了Java,C#語法的abstract抽象類的設(shè)計思想肪笋。
-
getRootUrl
請求域名url月劈。默認(rèn)為nil,遵守實現(xiàn)者必須實現(xiàn)藤乙。 -
getPath
請求url后半部分猜揪。默認(rèn)為nil,遵守實現(xiàn)者必須實現(xiàn)坛梁。 -
getBaseHeader
基本header而姐。默認(rèn)為nil,若有每個請求必填的header字段划咐,請實現(xiàn)此方法拴念。 -
getHeader
基本header以外的請求header。默認(rèn)為nil褐缠,遵守實現(xiàn)者必須實現(xiàn)政鼠。 -
getBaseBody
基本body。默認(rèn)為nil队魏,若有每個請求必填的body字段公般,請實現(xiàn)此方法。 -
getBody
基本body以外的請求body胡桨。默認(rèn)為nil官帘,遵守實現(xiàn)者必須實現(xiàn) -
getRespClass
用來指定該請求返回的數(shù)據(jù)實體Class,遵守者重寫該方法需返回一個Class類型[Entity class]昧谊,將返回的數(shù)據(jù)轉(zhuǎn)換成指定數(shù)據(jù)實體對象刽虹。同時在同一頁面中發(fā)起n個不同api請求后,返回的數(shù)據(jù)揽浙,我們可以通過class來區(qū)別状婶。
3.BaseApi 請求Api基類
請求基類意敛,繼承自AbsApi
,且遵守了ApiDelegate
協(xié)議膛虫。
內(nèi)部實現(xiàn)了ApiDelegate
協(xié)議的方法草姻,大家使用時直接繼承BaseApi
。而如果BaseApi如果不符合你的口味稍刀,你可以來自定義一個繼承AbsApi又遵守BaseApiDelegate協(xié)議的對象
4.BaseServiceManager
用來使用AFNetWorking發(fā)送請求撩独,只是個管理者,本身并不具備發(fā)送請求能力账月;目前依賴于AFNetWorking來發(fā)送網(wǎng)絡(luò)請求综膀;在內(nèi)部封裝了一些默認(rèn)創(chuàng)建AFHTTPSessionManager
的方法。
/// 使用block方式發(fā)送數(shù)據(jù)請求局齿;api:發(fā)送參數(shù)剧劝,sucBlock:成功回調(diào),failBlock:失敗回調(diào)
- (void)request:(AbsApi<ApiDelegate>*)api
sucBlock:(RespSucBlock)sucBlock
failBlock:(RespFailBlock)failBlock;
該方法使用Block回調(diào)來發(fā)送請求抓歼,api參數(shù)為繼承AbsApi抽象類讥此,且遵守ApiDelegate
協(xié)議的對象,(PS:BaseApi就符合該約束谣妻,凡繼承BaseApi的對象都符合該參數(shù)約束
) BaseServiceManager
內(nèi)部通過api對象配置來發(fā)送請求萄喳。sucBlock
,failBlock
為請求成功/失敗回調(diào)蹋半。
5.RequestManager
繼承自BaseServiceManager他巨;設(shè)計此Manager主要目的是,后期不采用AFNetWorking時减江,可在本類的發(fā)送方法sendRequest...中切換其他第三方請求框架即可染突,而不需要項目中到處修改AFNetWorking請求為其他方式請求,同時擔(dān)任著控制第三方請求的角色辈灼;因此觉痛,即使看不慣本類,也不要修改茵休;另外,本類增加了Protocal回調(diào)數(shù)據(jù)方式請求手蝎。
/// ResponseDelegate 數(shù)據(jù)響應(yīng)回調(diào)協(xié)議
@property (nonatomic,assign) id<YResponseDelegate> ydelegate;
+ (id)initManagerWithDelegate:(id<ResponseDelegate>)delegate;
/// 發(fā)送數(shù)據(jù)請求榕莺,參數(shù)為繼承AbsApi抽象類,且遵守BaseApiDelegate協(xié)議 的對象
- (void)sendRequest:(AbsApi<ApiDelegate>*)api;
我們可以直接使用initManagerWithYDelegate:
或者defaultManager
方法來初始化RequestManager對象棵介,將數(shù)據(jù)回調(diào)協(xié)議delegate傳入钉鸯。
使用request:
方法來發(fā)送請求,同父類一致邮辽,api參數(shù)為繼承AbsApi抽象類唠雕,且遵守BaseApiDelegate
協(xié)議的對象贸营。而上述BaseApi
就符合這一點,而BaseApi如果不符合你的口味岩睁,你可以來自定義一個繼承AbsApi又遵守BaseApiDelegate協(xié)議的對象钞脂。
使用方式
1.Api配置類
- Api配置類使用
// 導(dǎo)入
#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];
// 設(shè)置配置:請求body參數(shù)
api.user = @"andy";
api.pwd = @"pwd";
2.RequestManager請求
- RequestManager請求
#import "RequestManager.h"
// 初始化請求管理類
RequestManager *reqManager = [RequestManager defaultManager:self];
// 添加響應(yīng)成功后,數(shù)據(jù)轉(zhuǎn)換實體方式攔截器
[reqManager setInterceptorForSuc:[DataConvertInterceptor new]];
// 發(fā)送請求:Protocol方式接收數(shù)據(jù)
[reqManager request:api];
// 發(fā)送請求:Block方式接收數(shù)據(jù)
[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并非框架自帶捕儒,因為框架不應(yīng)該綁架業(yè)務(wù)層使用什么做數(shù)據(jù)轉(zhuǎn)換冰啃,
因此,這個過程開放出來刘莹,自行決定阎毅。(示例代碼中是使用yyModel轉(zhuǎn)換)
@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轉(zhuǎn)換成目標(biāo)實體
Class cls = api.getRespClass;
resp.data = [cls yy_modelWithDictionary:dic];
return resp;
}
@end