前言
AFNetworking為我們封裝了一系列的網(wǎng)絡(luò)服務(wù),直接使用基本上可以滿足大多數(shù)需求。隨著需求不斷增加,架構(gòu)不斷完善,直接使用AFNetworking未免會代碼冗余,于是就出現(xiàn)了各種對AFNetworking的二次封裝。
現(xiàn)有的AFNetworking二次封裝優(yōu)秀框架
-
YTKNetworking
YTKNetwork是基于AFNetworking的高級請求實用,適用于稍微復(fù)雜的項目,而不適用于簡單的個人項目 -
PPNetworkHelper
PPNetworkHelper對AFNetworking 3.x 與YYCache的二次封裝,封裝常見的GET、POST、文件上傳/下載、網(wǎng)絡(luò)狀態(tài)監(jiān)測的功能、方法接口簡潔明了,并結(jié)合YYCache實現(xiàn)對網(wǎng)絡(luò)數(shù)據(jù)的緩存,簡單易用,不用再寫FMDB那煩人的SQL語句,一句代碼搞定網(wǎng)絡(luò)數(shù)據(jù)的請求與緩存. 無需設(shè)置,無需插件,控制臺可直接打印json中文字符,調(diào)試更方便 -
XMNetworking
XMNetworking是一個輕量的,簡單易用但功能強大的網(wǎng)絡(luò)庫
一套適合公司業(yè)務(wù)的網(wǎng)絡(luò)框架
YTKNetworking 與 PPNetworkHelper都是面向相對復(fù)雜的項目而生,我們沒用到緩存部分,同時我們更傾向于輕量級的網(wǎng)絡(luò)框架。但是我們又崇尚YTKNetworking那樣的風(fēng)格,結(jié)合當(dāng)前項目架構(gòu),借鑒 XMNetworking,于是寫了能cover住的HKHttpManager。
解釋 HKHttpManager
HKHttpManager 由configure、logger、manager、response、request組成。
-
request的組成
/**
請求 Base URL,優(yōu)先級高于 [HKHttpConfigure generalServer];
*/
@property (nonatomic, copy) NSString *baseURL;
/**
請求路徑 eg: /login2
*/
@property (nonatomic, copy) NSString *requestURL;
/**
請求頭,默認(rèn)為空 @{}
*/
@property (nonatomic, strong) NSDictionary *requestHeader;
/**
請求參數(shù),加密參數(shù) 默認(rèn)為空 @{}
*/
@property (nonatomic, strong) NSDictionary *encryptParams;
/**
請求參數(shù),不用加密 默認(rèn)為 @{}
*/
@property (nonatomic, strong) NSDictionary *normalParams;
/**
請求方式 默認(rèn)為 HKRequestTypePost
*/
@property (nonatomic, assign) HKHttpRequestType requestMethod;
/**
請求方式string
*/
@property (nonatomic,copy) NSString *requestMethodName;
/**
請求超時時間 默認(rèn) 30s
*/
@property (nonatomic, assign) NSTimeInterval reqeustTimeoutInterval;
/**
api 版本號,默認(rèn) 1.0
*/
@property (nonatomic, copy) NSString *apiVersion;
/**
重試次數(shù),默認(rèn)為 0
*/
@property (nonatomic, assign) UInt8 retryCount NS_UNAVAILABLE;
/**
生成請求
@return NSURLRequest
*/
- (NSURLRequest *)generateRequest;

三個Request類
以上屬性都可以再在初始化之后設(shè)置,并且都設(shè)置了默認(rèn)值。同時有些相同的部分你也可以修改
generateRequest,無論是chainRequest還是groupRequest都需要以HKHttpRequest為請求request。chainRequest和groupRequest某種意義上都是為了在HKHttpmanager調(diào)用方便而封裝。
-
HKHttpmanager組成
HKHttpManager主要提供發(fā)起請求接口,普通請求可通過block賦值request。
/**
直接進行請求,不進行參數(shù)及 url 的包裝
@param request 請求實體類
@param result 響應(yīng)結(jié)果
@return 該請求對應(yīng)的唯一 task id
*/
- (NSString *_Nullable)sendRequest:(nonnull HKHttpRequest *)request complete:(nonnull HKHttpResponseBlock) result;
/**
發(fā)送網(wǎng)絡(luò)請求,緊湊型
@param requestBlock 請求配置 Block
@param result 請求結(jié)果 Block
@return 該請求對應(yīng)的唯一 task id
*/
- (NSString *_Nullable)sendRequestWithConfigBlock:(nonnull HKRequestConfigBlock )requestBlock complete:(nonnull HKHttpResponseBlock) result;
-
HKHttpManager+Group與HKHttpManager+Chain
特意將Group和Chain封裝成了類別,單獨處理HKHTTPGroupRequest、HKHttpChainRequest并行串行等關(guān)系,在這里將request序列化,再調(diào)用sendRequest:請求。
- (NSString *)sendGroupRequest:(nullable HKGroupRequestConfigBlock)configBlock
complete:(nullable HKGroupResponseBlock)completeBlock;
- (void)cancelGroupRequest:(NSString *)taskID;
@end

結(jié)構(gòu)圖.png
使用 HKHttpManager
普通 request
-
#import "HKHttpManagerHeader.h",建議在APPDelegate初始化baseURL
[HKHttpConfigure shareInstance].generalServer = @"https://www.apiopen.top/";
- 根據(jù)需要設(shè)置公共請求頭
generalHeaders、公共參數(shù)generalParameters
[HKHttpConfigure shareInstance].generalHeaders = @{@"token":token};
[HKHttpConfigure shareInstance].generalParameters = @{@"openid":@"xxx"};
- 構(gòu)建
request
HKHttpRequest *request = [[HKHttpRequest alloc] init];
request.requestURL = @"satinApi";
request.normalParams = @{@"type":@"1",
@"page":@"1"
};
request.requestMethod = HKHttpRequestTypeGet;
4.發(fā)起請求
[[HKHttpManager shareManager] sendRequest:request complete:^(HKHttpResponse * _Nullable response) {
NSLog(@"%@",response.content);
}];
或者在block里構(gòu)建request
[[HKHttpManager shareManager] sendRequestWithConfigBlock:^(HKHttpRequest * _Nullable request) {
request.requestURL = @"satinApi";
request.normalParams = @{@"type":@"1",
@"page":@"1"
};
request.requestMethod = HKHttpRequestTypeGet;
} complete:^(HKHttpResponse * _Nullable response) {
if (response.status == HKHttpResponseStatusSuccess) {
NSLog(@"%@",response.content);
}
}];
使用chainQequest實現(xiàn)鏈?zhǔn)秸埱?/h5>
[[HKHttpManager shareManager] sendChainRequest:^(HKHttpChainRequest * _Nullable chainRequest) {
[chainRequest onFirst:^(HKHttpRequest * _Nullable request) {
request.requestURL = @"satinApi";
request.normalParams = @{@"type":@"1",
@"page":@"1"
};
request.requestMethod = HKHttpRequestTypeGet;
}];
[chainRequest onNext:^(HKHttpRequest * _Nullable request, HKHttpResponse * _Nullable responseObject, BOOL * _Nullable isSent) {
request.requestURL = @"satinApi";
request.normalParams = @{@"type":@"1",
@"page":@"2"
};
request.requestMethod = HKHttpRequestTypeGet;
}];
[chainRequest onNext:^(HKHttpRequest * _Nullable request, HKHttpResponse * _Nullable responseObject, BOOL * _Nullable isSent) {
request.requestURL = @"satinApi";
request.normalParams = @{@"type":@"1",
@"page":@"3"
};
request.requestMethod = HKHttpRequestTypeGet;
}];
} complete:^(NSArray<HKHttpResponse *> * _Nullable responseObjects, BOOL isSuccess) {
}];
使用groupQequest實現(xiàn)無序批量請求
[[HKHttpManager shareManager] sendGroupRequest:^(HKHttpGroupRequest * _Nullable groupRequest) {
for (NSInteger i = 0; i < 5; i ++) {
HKHttpRequest *request = [[HKHttpRequest alloc] init];
request.requestURL = @"satinApi";
request.normalParams = @{@"type":@"1",
@"page":@"1"
};
request.requestMethod = HKHttpRequestTypeGet;
[groupRequest addRequest:request];
}
} complete:^(NSArray<HKHttpResponse *> * _Nullable responseObjects, BOOL isSuccess) {
}];
TODO
[[HKHttpManager shareManager] sendChainRequest:^(HKHttpChainRequest * _Nullable chainRequest) {
[chainRequest onFirst:^(HKHttpRequest * _Nullable request) {
request.requestURL = @"satinApi";
request.normalParams = @{@"type":@"1",
@"page":@"1"
};
request.requestMethod = HKHttpRequestTypeGet;
}];
[chainRequest onNext:^(HKHttpRequest * _Nullable request, HKHttpResponse * _Nullable responseObject, BOOL * _Nullable isSent) {
request.requestURL = @"satinApi";
request.normalParams = @{@"type":@"1",
@"page":@"2"
};
request.requestMethod = HKHttpRequestTypeGet;
}];
[chainRequest onNext:^(HKHttpRequest * _Nullable request, HKHttpResponse * _Nullable responseObject, BOOL * _Nullable isSent) {
request.requestURL = @"satinApi";
request.normalParams = @{@"type":@"1",
@"page":@"3"
};
request.requestMethod = HKHttpRequestTypeGet;
}];
} complete:^(NSArray<HKHttpResponse *> * _Nullable responseObjects, BOOL isSuccess) {
}];
groupQequest實現(xiàn)無序批量請求 [[HKHttpManager shareManager] sendGroupRequest:^(HKHttpGroupRequest * _Nullable groupRequest) {
for (NSInteger i = 0; i < 5; i ++) {
HKHttpRequest *request = [[HKHttpRequest alloc] init];
request.requestURL = @"satinApi";
request.normalParams = @{@"type":@"1",
@"page":@"1"
};
request.requestMethod = HKHttpRequestTypeGet;
[groupRequest addRequest:request];
}
} complete:^(NSArray<HKHttpResponse *> * _Nullable responseObjects, BOOL isSuccess) {
}];
HKHttpManager目前能滿足公司的業(yè)務(wù),但是許多細(xì)節(jié)方面還需優(yōu)化,例如:
- 實現(xiàn)斷點續(xù)傳
-
groupRequest和chainRequest與request一致,支持兩種請求方式(目前只能在block中對groupRequest、chainRequest賦值)。 -
configure這方面還需要優(yōu)化,增加對request默認(rèn)請求的配置
End
GitHub地址在這里: HKHttpManager
謝謝各位閱讀,能力有限,希望大家能多提點優(yōu)化建議和看法!
我的組件化系列文章:
《iOS組件化》組件化實踐
《iOS組件化》組件的劃分
《iOS組件化》創(chuàng)建公共/私有 Pods
《iOS組件化》之使用AOP代替繼承
《iOS組件化》之 搭建適合業(yè)務(wù)的URL跳轉(zhuǎn)路由-ALRouter