[這是第二篇]
導(dǎo)語:去年中旬隅俘,為了精簡(jiǎn)網(wǎng)絡(luò)層的工作,為業(yè)務(wù)定制了一個(gè)iOS的網(wǎng)絡(luò)組件笤喳。這套組件頑強(qiáng)地在線上跑了大半年为居,沒犯什么錯(cuò)(謝天謝地,否者就真的是ZUO DIE -> GO DIE)杀狡。
一蒙畴、背景
a、原先的網(wǎng)絡(luò)層組件從別的項(xiàng)目借鑒來的呜象。網(wǎng)絡(luò)組件中耦合些和我們無關(guān)的業(yè)務(wù)膳凝,使用起來代碼寫好長(zhǎng),簡(jiǎn)單定義一個(gè)請(qǐng)求大概需要100行左右恭陡,處理起來也是比較辛苦
b蹬音、大家做網(wǎng)絡(luò)數(shù)據(jù)落地處理的方式,沒有統(tǒng)一的方式(通知休玩,代理等,就是不使用block)
c著淆、AFNetworking3.0當(dāng)時(shí)出來好長(zhǎng)一段時(shí)間了劫狠,很多app網(wǎng)絡(luò)層面臨了網(wǎng)絡(luò)組件的替換可能
d、主要還是用得太辛苦牧抽,想借著AFNetworking3.0的東風(fēng)嘉熊,來好好升級(jí)一下網(wǎng)絡(luò)組件
二、業(yè)務(wù)目標(biāo)
在一個(gè)app開發(fā)中扬舒,設(shè)計(jì)iOS的網(wǎng)絡(luò)組件阐肤,需要考慮業(yè)務(wù)中實(shí)際遇到的需求。
1) post請(qǐng)求還是get請(qǐng)求
2) 普通數(shù)據(jù)請(qǐng)求 && 分頁數(shù)據(jù)請(qǐng)求讲坎,前者就是數(shù)據(jù)的一次性買賣孕惜,后者是連續(xù)不斷請(qǐng)求分頁數(shù)據(jù)
3) 連續(xù)的重復(fù)請(qǐng)求處理 (下拉刷新等場(chǎng)景下)
4) 請(qǐng)求簽名(請(qǐng)求數(shù)據(jù)的MD5校驗(yàn))
5) Cookie的處理(主要包含登錄用戶的標(biāo)識(shí)信息)
6) 統(tǒng)一的數(shù)據(jù)回調(diào)處理 (block處理)
7) 請(qǐng)求數(shù)據(jù)的緩存策略
三、業(yè)務(wù)使用
3.1晨炕、一般網(wǎng)絡(luò)數(shù)據(jù)返回格式協(xié)議
{
"code": 0,
"msg": "ok",
"data": ...
}
- code描述的的是服務(wù)器返回請(qǐng)求的狀態(tài)碼衫画,code為0時(shí),表示請(qǐng)求成功瓮栗,msg是狀態(tài)碼描述削罩。請(qǐng)求成功對(duì)應(yīng)ok。code為非0時(shí)候费奸,msg描述的就是錯(cuò)誤信息弥激。
- data對(duì)應(yīng)的內(nèi)容封裝的是返回的請(qǐng)求數(shù)據(jù),數(shù)據(jù)可以是數(shù)組(分頁請(qǐng)求中)愿阐,數(shù)據(jù)可以是字典結(jié)構(gòu)(一般請(qǐng)求微服,如詳情頁請(qǐng)求)
- 返回的網(wǎng)絡(luò)數(shù)據(jù)可以解析成model,本質(zhì)是JSON轉(zhuǎn)Model缨历,這部分工作可以交給第三方庫JSONModel或YYModel以蕴,然后把數(shù)據(jù)model交給業(yè)務(wù)層去使用。
3.2辛孵、普通請(qǐng)求(非分頁)的處理
1) 初始化請(qǐng)求
+ (QCBaseRequest *)normalRequestWithUrl:(NSString *)urlString
parameters:(nullable NSDictionary *)parameters
requestMethodType:(QCRequestMethodType)requestMethodType
2) 發(fā)出請(qǐng)求
- (void)startWithCompleteBlock:(QCRequestCompleteBlock)completeBlock;;
3) 使用
self.request = [QCBaseRequest normalRequestWithUrl:urlString parameters:nil requestMethodType:QCRequestMethodTypeGET];
[self.request startWithCompleteBlock:^(BOOL isSuccess, id _Nullable responseObj, NSString * _Nonnull errorDesc) {
NSLog(@"isSuccess = %d && errorDesc = %@",isSuccess,errorDesc);
//TODO 數(shù)據(jù)解析....
}];
3.3丛肮、分頁請(qǐng)求的處理
- 在app中,通常列表頁都支持分頁請(qǐng)求魄缚。請(qǐng)求中添加page和pagesize的參數(shù)值(pagesize一般是固定的)宝与,然后服務(wù)器根據(jù)相關(guān)信息返回對(duì)應(yīng)頁的數(shù)據(jù)。
1) 初始化請(qǐng)求
+ (QCBaseRequest *)pagingRequestWithMethodType:(QCRequestMethodType)requestMethodType
parameters:(nullable NSDictionary *)parameters;
2)使用
- (void)startPagingRequestUrl:(NSString *)urlString
completeBlock:(QCPageRequestCompleteBlock)completeBlock
3) 使用
[self.pagingRequest startPagingRequestUrl:urlString completeBlock:^(BOOL isSuccess, BOOL hasMoreData, BOOL isReset, id _Nullable dataArray, NSString * _Nonnull errorDesc) {
NSLog(@"isSuccess = %d && hasMoreData = %d && isReset = %d",isSuccess,hasMoreData,isReset);
NSLog(@"&& errorDesc = %@",errorDesc);
}];
3.4鲜滩、取消請(qǐng)求
- 取消請(qǐng)求的操作還是很有必要的伴鳖。主要是處于以下兩個(gè)原因:
- 一個(gè)是考慮安全。如在Controller了中發(fā)出請(qǐng)求徙硅,請(qǐng)求沒有返回這段時(shí)間內(nèi)榜聂,用戶點(diǎn)擊去了另一個(gè)Controller,或者退出了當(dāng)前的Controller嗓蘑,請(qǐng)求還未回來须肆,一旦系統(tǒng)回收了這個(gè)Controller匿乃,數(shù)據(jù)落地Controller無法處理,這樣就埋下了隱患豌汇。
- 另一個(gè)是為了及時(shí)更新請(qǐng)求幢炸。如用戶下拉操作時(shí)候,同樣的請(qǐng)求連續(xù)發(fā)出拒贱,通過取消前一個(gè)請(qǐng)求宛徊,保證最新發(fā)出的請(qǐng)求有效。當(dāng)然我們也可以不取消請(qǐng)求逻澳,檢測(cè)前一個(gè)相同請(qǐng)求沒有落地闸天,后續(xù)相同的請(qǐng)求無效的情況。(我的網(wǎng)絡(luò)組件默認(rèn)是這么做的)
四斜做、總結(jié)
- 早期苞氮,我們采用的是離散式的網(wǎng)絡(luò)請(qǐng)求API去處理請(qǐng)求(一個(gè)請(qǐng)求對(duì)應(yīng)一個(gè)API),這給了我們極大的自由瓤逼,如分頁請(qǐng)求處理等笼吟。但是隨著業(yè)務(wù)增加,請(qǐng)求的類文件越來越多霸旗,冗余的代碼也越來越多贷帮。
- 雖然我們需要自由,但是在我這一年的開發(fā)中發(fā)現(xiàn)定硝,業(yè)務(wù)中似乎不太需要這種自由皿桑,規(guī)范極大地約束了自由毫目,不需要開發(fā)者太多變化蔬啡。這些規(guī)范目前看來,沒有不好地方(技術(shù)不是為了炫技镀虐,應(yīng)該是更好服務(wù)于業(yè)務(wù)吧箱蟆,"死板"些似乎也沒有錯(cuò))。
- 網(wǎng)絡(luò)層業(yè)務(wù)組件一直提供離散式的網(wǎng)絡(luò)請(qǐng)求API刮便,現(xiàn)在的集約式請(qǐng)求API正是建立在原來離散式的網(wǎng)絡(luò)請(qǐng)求API的基礎(chǔ)上的空猜。(繞了一大圈又回來了)
源碼直通車 : QSUseNetworkDemo