淺談網(wǎng)絡(luò)層設(shè)計(jì)(XXHNetwork封裝緩存碎节、日志輸出、參數(shù)抵卫,返回?cái)?shù)據(jù)攔截控制等)

  • 對于網(wǎng)絡(luò)層的設(shè)計(jì)狮荔,相信大家都不會(huì)陌生胎撇,最知名當(dāng)屬于AFNetworking。但是我們實(shí)際開發(fā)過程中網(wǎng)絡(luò)層的任務(wù)不僅僅需要單純的網(wǎng)絡(luò)請求轴合,而是需要處理關(guān)于請求數(shù)據(jù)相關(guān)的整個(gè)一大塊创坞,例如:數(shù)據(jù)緩存、日志受葛、code校對、錯(cuò)誤分析等等偎谁。我們希望網(wǎng)絡(luò)層能起到后臺(tái)與實(shí)際業(yè)務(wù)的橋梁作用总滩,同時(shí)網(wǎng)絡(luò)層不可以染指業(yè)務(wù)邏輯⊙灿辏考慮低耦合要求闰渔,我們往往會(huì)把網(wǎng)絡(luò)層設(shè)計(jì)成一個(gè)獨(dú)立模塊。而我們大名頂頂?shù)腁FNetworking并不能實(shí)現(xiàn)這一多功能要求铐望,那么我們就需要對AFNetworking二次封裝增加新的功能以滿足我們所需要的網(wǎng)絡(luò)層要求冈涧。

一、如何設(shè)計(jì)(個(gè)人淺談)

  • 1.封裝形式:對AFNetworking封裝分為兩種形式正蛙,block(集約型)和代理(離散型)督弓。所以我們需要對這兩種進(jìn)行選擇。
  • 2.緩存模塊:業(yè)務(wù)有時(shí)候需要一些重要對數(shù)據(jù)能夠緩存下來而不是每次請求網(wǎng)絡(luò)乒验。所以我們需要一個(gè)緩存數(shù)據(jù)的模塊愚隧。
  • 3.日志系統(tǒng):對于每次請求我們不可能說每次都能一次性搞定,而是需要跟后臺(tái)不斷調(diào)試锻全,包括我們自己調(diào)試狂塘,這樣我們就需要一個(gè)日志模塊,這個(gè)模塊能夠打印出關(guān)于請求的所有信息鳄厌,成功能夠打印出正確數(shù)據(jù)荞胡,失敗能夠打印具體的失敗信息等,我們只需要簡單看看日志就能發(fā)現(xiàn)問題所在而不是通過LLDB打斷點(diǎn)一步一步調(diào)試找出錯(cuò)誤了嚎。
  • 4.低偶合性泪漂。網(wǎng)絡(luò)層必須是一個(gè)獨(dú)立的模塊,不能夠跟業(yè)務(wù)邏輯糾纏在一起新思。對于網(wǎng)絡(luò)層來講窖梁,我只給你業(yè)務(wù)提供數(shù)據(jù),至于你要用數(shù)據(jù)去干什么夹囚,我并不關(guān)心纵刘。另一方面,網(wǎng)絡(luò)層必須跟AFNetworking低耦合荸哟,一旦哪天我們不想要用AFNetworking可以輕松替換假哎。
  • 5:可操控性:很多時(shí)候會(huì)出現(xiàn)這種情況瞬捕,我們給的請求參數(shù)明顯不對,或者后臺(tái)返回的數(shù)據(jù)明顯不是業(yè)務(wù)需求數(shù)據(jù)舵抹。如果我們不加以處理肪虎,那么就會(huì)導(dǎo)致請求錯(cuò)誤,并且這個(gè)錯(cuò)誤數(shù)據(jù)流入地業(yè)務(wù)端惧蛹,業(yè)務(wù)端首先需要去甄別數(shù)據(jù)的好壞扇救,其次再加以使用。一旦業(yè)務(wù)的請求接口過多勢必會(huì)導(dǎo)致業(yè)務(wù)層壓力增大香嗓。對此迅腔,我們需要將這些不必要的錯(cuò)誤扼殺在網(wǎng)絡(luò)層, 所以一些時(shí)候網(wǎng)絡(luò)層需要對請求的參數(shù)靠娱,以及返回的數(shù)據(jù)進(jìn)行校對沧烈,或者修訂。這樣可以減少業(yè)務(wù)層的壓力負(fù)擔(dān)像云,使其能更好的關(guān)注業(yè)務(wù)邏輯锌雀。
  • 6.簡單,易懂的代碼:有些簡單的請求如果進(jìn)行一系列分析的話有會(huì)導(dǎo)致代碼看上去很煩亂迅诬,所以我們還需要提供一些簡單易懂的調(diào)用方法腋逆。
  • 7.請求控制:一些沒有必要的請求我們需要及時(shí)去除。例如:切換頁面后百框,請求還在進(jìn)行闲礼,這時(shí)候請求已經(jīng)沒有必要了,我們需要停止铐维,防止流量的浪費(fèi)柬泽,同時(shí)對于一些麻煩的請求(大數(shù)據(jù)的上傳下載等)還可以提升流暢度。

二嫁蛇、模式缺陷

1.block形式的缺陷

  • block不夠安全锨并,稍微不注意就形成循環(huán)引用,導(dǎo)致對象釋放不了睬棚。這種循環(huán)引用第煮,一旦出現(xiàn)就比較難檢查出來。
  • block很難追蹤抑党,難以維護(hù)
  • block會(huì)延長相關(guān)對象的生命周期
  • 在多通信時(shí)候包警,block顯得不夠直觀也不易維護(hù)
  • block效率低,block出棧需要將使用的數(shù)據(jù)從棧內(nèi)存拷貝到堆內(nèi)存

2.block形式的優(yōu)點(diǎn)

  • 使用更簡單底靠,易維護(hù)害晦,能夠直接訪問上下文,獲取數(shù)據(jù)方便
  • 省去了寫代理的很多代碼

3.delegate形式的優(yōu)點(diǎn)

  • delegate更安全暑中, delegate 的方法是分離開的壹瘟,不會(huì)引用上下文鲫剿,不容易循環(huán)引用
  • 代碼的連貫性不是很好,沒有 block 好讀
  • delegate 讓多個(gè)方法分成一組稻轨,只需要設(shè)置一次灵莲,就可以多次回調(diào)。即同一個(gè)請求可能會(huì)多次調(diào)用的時(shí)候delegate只需要設(shè)置一次殴俱,而block需要多次政冻,這種情況下也推薦用delegate形式
  • delegate運(yùn)行成本低,delegate只是保存了一個(gè)對象指針线欲,直接回調(diào)赠幕,沒有額外消耗

3.delegate形式的缺點(diǎn)

  • 使用繁瑣,請求接口數(shù)量多的時(shí)候delegate要寫更多的代碼询筏。
  • 方法的聲明和實(shí)現(xiàn)分離開來,代碼的連貫性不是很好竖慧。
  • 需要臨時(shí)存儲(chǔ)很多數(shù)據(jù)嫌套,跟業(yè)務(wù)交接不方便

三、個(gè)人方案

1.業(yè)務(wù)分析

  • 開始公司業(yè)務(wù)量不多的時(shí)候圾旨,接口較少踱讨,也比較簡單。自己用的都是block形式砍的,輕型痹筛、簡單、代碼易讀易修改廓鞠。這樣一方面符合剛開始的快速迭代帚稠,二方面也節(jié)省時(shí)間。但是隨著后來業(yè)務(wù)量的增加床佳,業(yè)務(wù)功能的細(xì)致化后發(fā)現(xiàn)滋早,自己的業(yè)務(wù)層開始變的非常臃腫,對于一些接口砌们,業(yè)務(wù)還需要去自己檢測數(shù)據(jù)的格式符不符合要求杆麸。一些相同的請求,多次不同地方調(diào)用浪感,block就的在多個(gè)地方多次重寫等等導(dǎo)致業(yè)務(wù)層再次變的繁瑣...

2.問題處理 - XXHNetwork

  • 對于相同接口多次調(diào)用等問題我們應(yīng)該使用delegate模式昔头,但由于之前使用大量的block一時(shí)間全部更換不現(xiàn)實(shí),而且一些簡單的接口更換后反而顯得臃腫影兽,所以最終采用但是混合模式揭斧,即網(wǎng)絡(luò)層最外層即提供block形式接口,同時(shí)也提供delegate形式接口赢笨,至于需要用哪種形式未蝌,可由開發(fā)人員根據(jù)業(yè)務(wù)需求自行選擇驮吱,以達(dá)到最優(yōu)效果。

四萧吠、XXHNetwork封裝緩存左冬、日志輸出、參數(shù)纸型,返回?cái)?shù)據(jù)攔截控制

1.數(shù)據(jù)緩存

XXHNetwork提供了獨(dú)立的緩存模塊(XHNetworkCacheManager)該模塊底層運(yùn)用的是YYCache,因?yàn)閅YCache LRU算法比較符合我們現(xiàn)實(shí)的使用場景拇砰,當(dāng)然我們系統(tǒng)提供的NSCache也是ok的,看個(gè)人喜好吧狰腌。緩存模塊提供下面功能

  • 支持最大緩存數(shù)量
  • 緩存版本控制除破、app版本檢測
  • 根據(jù)請求shouldAllIgnoreCache判斷是否需要緩存
  • 緩存的有效時(shí)長
  • 內(nèi)存、磁盤兩中存儲(chǔ)方式
  • 緩存數(shù)據(jù)增琼腔、刪瑰枫、改、查

2.日志輸出

日志輸出由獨(dú)立的模塊XHNetworkLogManager控制丹莲,里面提供各種情況(成功光坝、失敗)下日志輸出接口甥材,只需要調(diào)用初始化方法傳入相應(yīng)數(shù)據(jù)即可盯另!

  • func appendURL:用于打印請求head、body信息
  • func logDebugInfo:用于打印請求返回?cái)?shù)據(jù)信息
    當(dāng)然你也可以根據(jù)自己的需求在這個(gè)模塊增加日志收集接口等等個(gè)人業(yè)務(wù)相關(guān)等需求

3.底層接口分離

  • XXHNetwork跟底層AF交互的只有XHApiProxy一個(gè)類洲赵,同時(shí)只有一個(gè)方法(func callNetwork)這一個(gè)方法跟AF交互鸳惯,其他所有不同方式請求處理都是通過調(diào)用該方法,也就是以后如果想替換AFNetworking那么只需要更換這一個(gè)方法即可替換非常方便叠萍!
  • 底層方法callNetwork還增加了一些基本的code處理芝发,對于一些明顯的錯(cuò)誤,例如token失效等俭令,這里直接放在最底層進(jìn)行處理這樣只需要處理一次即可后德。
  • XHApiProxy提供供外界調(diào)用基本請求接口,同時(shí)還提供了請求控制接口抄腔,可以實(shí)現(xiàn)部分或者全部取消請求瓢湃。

4.上層接口

  • block形式:XHNetworkBlockManager,只要實(shí)現(xiàn)相應(yīng)的成功赫蛇、失敗回調(diào)即可绵患,相關(guān)的錯(cuò)誤類型查看XHNetworkErrorType
  • delegate形式:XHNetworkDelegateManager,這個(gè)可用于參數(shù)控制悟耘,數(shù)據(jù)返回檢測落蝙,只要實(shí)現(xiàn)相應(yīng)的代理即可實(shí)現(xiàn)相應(yīng)功能,詳細(xì)看注釋。
  • XHNetworkConfigution:網(wǎng)絡(luò)配置,網(wǎng)絡(luò)基本配置在這里修改
  • XHNetworkRequestConfig:請求配置筏勒,你可以根據(jù)業(yè)務(wù)需求初始化具體的配置移迫,你也可以不用管使用默認(rèn)的請求配置。
  • XHURLResponse:返回?cái)?shù)據(jù)對象管行,不管成功還是失敗都會(huì)返回該對象厨埋,該對象包含了所有需要信息,AN返回的基本數(shù)據(jù)responseObject為(content)捐顷,error:為錯(cuò)誤信息荡陷。其他信息請查看注釋。

5.使用

  • block使用:
XHNetworkBlockManager.shared.request(Method: XHNetworkRequestType.get, APIString: "", Parameters: params, SuccessBlock: { (successResponse) in
            print("--------------方式一(block形式)請求數(shù)據(jù)成功----------")
            self.testManager.loadData()
        }) { (failureResponse) in
            print("--------------方式一請求數(shù)據(jù)失敗----------")
        }
  • delegate使用:
    1.創(chuàng)建一個(gè)繼承XHNetworkDelegateManager的業(yè)務(wù)請求中間管理類:XHNetworkTestManager迅涮。這個(gè)類專門來實(shí)現(xiàn)一些公用的業(yè)務(wù)代理XHAPIManagerValidator废赞、XHAPIManager等當(dāng)然你也可以不用,那么你的代理實(shí)現(xiàn)就必須在具體的業(yè)務(wù)中叮姑,這樣會(huì)增加業(yè)務(wù)代碼量唉地,所以不推薦。
    2.調(diào)用
    統(tǒng)一加載方法: loadData
    加載更多方法:loadMoreData
//代理方式調(diào)用
self.testManager.loadData()

3.在具體業(yè)務(wù)中創(chuàng)建一個(gè)中間管理類的對象testManager
然后在業(yè)務(wù)接著完成剩余代理的實(shí)現(xiàn)

lazy var testManager:XHNetworkTestManager = {
        
        let testManager = XHNetworkTestManager()
        testManager.callBackDelagate = self
        testManager.paramSourceDelegate = self
        return testManager
    }()
//參數(shù)代理传透,在這里傳送請求參數(shù)
    func configeApiParams(Manager manager: XHNetworkDelegateManager) -> [String : Any]? {
        
        let dic = [String : Any]()
        return dic
    }
    //返回?cái)?shù)據(jù)代理
    func requesApiSuccess(Manager manager: XHNetworkDelegateManager) {
        print("--------------方式二(delegate形式)請求數(shù)據(jù)成功----------")
    }
    
    func requesApiFailure(Manager manager: XHNetworkDelegateManager) {
        print("--------------方式二請求數(shù)據(jù)失敗----------")
    }

源碼地址請點(diǎn)擊這里渣蜗,歡迎大神指導(dǎo),若考慮不周的地方旷祸,請大家多提意見!如果喜歡或者對您有幫助讼昆,希望能給個(gè)小星星托享,多謝!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末浸赫,一起剝皮案震驚了整個(gè)濱河市闰围,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌既峡,老刑警劉巖羡榴,帶你破解...
    沈念sama閱讀 211,817評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異运敢,居然都是意外死亡校仑,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,329評論 3 385
  • 文/潘曉璐 我一進(jìn)店門传惠,熙熙樓的掌柜王于貴愁眉苦臉地迎上來迄沫,“玉大人,你說我怎么就攤上這事卦方⊙虼瘢” “怎么了?”我有些...
    開封第一講書人閱讀 157,354評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長尘吗。 經(jīng)常有香客問我逝她,道長,這世上最難降的妖魔是什么睬捶? 我笑而不...
    開封第一講書人閱讀 56,498評論 1 284
  • 正文 為了忘掉前任黔宛,我火速辦了婚禮,結(jié)果婚禮上侧戴,老公的妹妹穿的比我還像新娘宁昭。我一直安慰自己,他們只是感情好酗宋,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,600評論 6 386
  • 文/花漫 我一把揭開白布积仗。 她就那樣靜靜地躺著,像睡著了一般蜕猫。 火紅的嫁衣襯著肌膚如雪寂曹。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,829評論 1 290
  • 那天回右,我揣著相機(jī)與錄音隆圆,去河邊找鬼。 笑死翔烁,一個(gè)胖子當(dāng)著我的面吹牛渺氧,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播蹬屹,決...
    沈念sama閱讀 38,979評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼侣背,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了慨默?” 一聲冷哼從身側(cè)響起贩耐,我...
    開封第一講書人閱讀 37,722評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎厦取,沒想到半個(gè)月后潮太,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,189評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡虾攻,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,519評論 2 327
  • 正文 我和宋清朗相戀三年铡买,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片霎箍。...
    茶點(diǎn)故事閱讀 38,654評論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡寻狂,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出朋沮,到底是詐尸還是另有隱情蛇券,我是刑警寧澤缀壤,帶...
    沈念sama閱讀 34,329評論 4 330
  • 正文 年R本政府宣布,位于F島的核電站纠亚,受9級特大地震影響塘慕,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜蒂胞,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,940評論 3 313
  • 文/蒙蒙 一图呢、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧骗随,春花似錦蛤织、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,762評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至涨椒,卻和暖如春摊鸡,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背蚕冬。 一陣腳步聲響...
    開封第一講書人閱讀 31,993評論 1 266
  • 我被黑心中介騙來泰國打工免猾, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人囤热。 一個(gè)月前我還...
    沈念sama閱讀 46,382評論 2 360
  • 正文 我出身青樓猎提,卻偏偏與公主長得像,于是被迫代替她去往敵國和親旁蔼。 傳聞我的和親對象是個(gè)殘疾皇子忧侧,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,543評論 2 349

推薦閱讀更多精彩內(nèi)容