談談 iOS 網絡層設計(SSJNetWork封裝緩衝,log日誌,自動取消網絡請求)

首先網絡層的基礎組件應該是AFNetworking 大部分開發人員都是基於AFNetworking的二次封裝,比較知名的就是CTNetWork和YTKNetwork,閱讀完源碼,我認爲和咱們的實際業務需求不符合,我認爲一個好的網絡層,應該還有如下特色html

  1. 簡單,易懂的代碼 
  2. 日誌輸出
  3. 緩存應該採用lru算法,由於一個開發人員不清楚用戶具體喜歡哪些內容,只能作重要界面的全部的緩衝,然而用戶可能某時間基於好奇心會點擊APP內大部分界面和形成大量緩衝,這種資源浪費是不必,因此我的感受要清除命中率不高的緩存
  4. 取消網絡請求

下面談一下比較知名的CTNetworking和YTKNetworkios


在 Casa Taloyum大神 iOS應用架構談 網絡層設計方案 的內容文章裏面,談論的兩大問題就是block和代理 集約型和離散型的技術點討論git

Casa Taloyum討論了block的在網絡層使用的時候缺點
  • block很難追蹤,難以維護
  • block會延長相關對象的生命週期
  • block在離散型場景下不符合使用的規範
集約型存在的問題
  • 緣由1:當前請求正在外面飛着的時候,根據不一樣的業務需求存在兩種不一樣的請求起飛策略:一個是取消新發起的請求,等待外面飛着的請求着陸。另外一個是取消外面飛着的請求,讓新發起的請求起飛。集約化的API調用方式若是要知足這樣的需求,那麼每次要調用的時候都要多寫一部分判斷和取消的代碼,手段就作不到很乾淨。
  • 緣由2:便於針對某個API請求來進行AOP。在集約型的API調用方式下,若是要針對某個API請求的起飛和着陸過程進行AOP,這代碼得寫成什麼樣。。。噢,尼瑪這畫面太美別說看了,我都不敢想。

  • 離散型的優勢

  • 緣由3:當API請求的着陸點消失時,離散型的API調用方式可以更加透明地處理這種狀況。
  • 緣由4:離散型的API調用方式可以最大程度地給業務方提供靈活性,好比reformer機制就是基於離散型的API調用方式的。另外,若是是針對提供翻頁機制的API,APIManager就能簡單地提供loadNextPage方法去加載下一頁,頁碼的管理就不用業務方去管理了。還有就是,若是要針對業務請求參數進行驗證,好比用戶填寫註冊信息,在離散型的APIManager裏面實現就會很是輕鬆。

筆者認爲「尺有所短寸有所長」每一個事物都有他的優勢和缺點,可能在某一類環境下A的優勢多,某一類環境下B的有點多了,這個問題只是相對的,例如在計算機當中,要麼用空間換時間,要麼時間換空間,魚和熊掌不可兼的。github

 block優勢:算法

  • 省去了寫代理的不少代碼
  • 2.block 更輕型,使用更簡單,可以直接訪問上下文,這樣類中不須要存儲臨時數據,使用 block 的代碼一般會在同一個地方,這樣能連貫讀代碼

 block缺點:  sql

  • 1.block不夠安全,使用 block 時稍微不注意就造成循環引用,致使對象釋放不了。這種循環引用,一旦出現就比較難檢查出來。
  •  2.block效率低,block出棧須要將使用的數據從棧內存拷貝到堆內存 3.在多個通訊事件的時候,block顯得不夠直觀也不易維護。

 delegate優勢:數據庫

 1.delegate更安全, delegate 的方法是分離開的,不會引用上下文,不容易循環引用 

      

 2.delegate效率高,delegate只是保存了一個對象指針 設計模式

3.在多個通訊事件的時候,delegate顯得直觀也易維護。

 delegate缺點:  緩存

  • 1.因方法的聲明和實現分離開來,代碼的連貫性不是很好,沒有 block 好讀 
  • 2.不少時候須要存儲一些臨時數據 ------------

筆者崇尚於更輕型,更簡單,更連貫的代碼,因此筆者在封裝SJNetwork的時候採用的是Block,佛家雲:有所舍,纔能有所得。安全


indulge_in 大神 認爲CTNetworking 不足:
  • 使用 IOP 方式創建模塊,化繼承爲組合。獨立<CTServiceProtocol><CTAPIManagerInterceptor>等協議做爲集約管理部分,若個別接口須要修改這些公共配置,只能在集約管理模塊來判斷,顯得有一點繁瑣。
  • 記錄了一個 request 實例的全部 task,在 dealloc 中自動取消掉還未降落的網絡請求,可是實際上網絡請求任務會持有 request,因此自動取消策略不成立了。


YTKNetwork 不足:
  • 基於多態的設計思路,提供了不少供重載的方法,從設計來看,框架是能夠實例化YTKBaseRequest子類 直接使用的,那麼直接使用時沒法重載這些方法專門定製(我的看來有些地方使用屬性更靈活);而且,當一個 reqeust 屢次start發起請求就會調用屢次這些重載方法,可能形成多餘計算;
  • 緩存策略使用一個YTKBaseRequest的子類YTKRequest來作,雖然這樣看起來比較優雅,父類和子類各司其職,單一職責,可是緩存策略不免會更改父類的邏輯,如此就很難不違背開閉原則。框架的緩存只有一個失效時間控制,筆者想要拓展時發現要改的東西太多。
  • 同一個 request 實例屢次 start 調用網絡請求時 (多個網絡請求併發狀況),並未做出實際的處理策略,僅保留最新的NSURLSessionTask,而對舊的未結束的全部NSURLSessionTask喪失了控制權。
  • 網絡請求任務強持有全部 request 對象,在弱網環境下可能會有大量 request 對象沒法釋放,而界面降落點可能不存在了。


CTNetworking

可讀性比YTKNetwork好

CTJsbridge已經能夠跟CTNetworking交互,H5工程師能夠很方便地使用基於CTNetworking的網絡API。

各類錯誤錯誤類型回調比較全

YTKNetwork

多是使用了命令模式的緣由吧,我覺的YTKNetwork的可讀性不如CTNetworking 我的覺的無論用什麼設計模式,爲的是代碼邏輯更加明確,代碼更加易懂易讀,若有不認同筆者的,請忽略,畢竟人生百味,請容許我有百想,

YTKNetwork和CTNetworking的日誌輸出,緩衝,取消網絡請求,當咱們使用的時候還的進行網絡的三次封裝,筆者認爲,一個網絡層設計,應該是都封裝進去,而後提供開發人員調用就能夠了,


SSJNetWork封裝緩衝,日誌,自動網絡請求。

1.緩存處理

緩存處理配置都在SJNetWorkConfig和SJNetworkRequestConfig類中,支持如下配置:

  • - 內存/磁盤存儲方式
  • - 緩存的有效時長
  • - 根據請求shouldAllIgnoreCache判斷是否須要緩存
  • - 以及直接配置 YYCache
  • - 支持緩衝最大數量(採用YYCache LRU算法)
  • - 緩存的版本

2. 自動取消網絡請求

採用AOP hook方式自動取消網絡請求

swizzling_exchangeMethod([self class],@selector(popViewControllerAnimated:), @selector(ssj_popViewControllerAnimated:));
swizzling_exchangeMethod([self class],@selector(popToRootViewControllerAnimated:), @selector(ssj_popToRootViewControllerAnimated:));
swizzling_exchangeMethod([self class],@selector(popToViewController:animated:), @selector(ssj_popToViewController:animated:));
swizzling_exchangeMethod([self class],@selector(dismissViewControllerAnimated:completion:), @selector(ssj_dismissViewControllerAnimated:completion:));
複製代碼

請配置 SJNetworkRequestConfigz 中 className 如不傳入參數網絡請求對應vc的className,則自動取消網絡請求無效

自動取消網絡請求根據的的是,視圖pop和dismiss的時候取消當前VC下全部的網絡請求設計的


3.日誌輸出,採用NetworkEye部分代碼能夠監控App內全部HTTP請求並顯示請求相關的全部信息,方便App開發的網絡調試

SJNetWorkConfig`變量配置,

dubugLogeEnable:請求完成控制檯直接輸出

SQLLogEnable:記錄在sql提升跳轉到vc的時候展現

ne_sqlitePassword:log日誌數據庫密碼

ne_saveRequestMaxCount:保存請求的最大個數


源碼地址  請點擊這裏,歡迎大神指導,若考慮不周的地方,請你們多提意見

相關文章
相關標籤/搜索