關于網絡層的架構

讀了Casa Taloyum老師的關于iOS應用架構談 網絡層設計方案這一篇文章后收獲頗多,這里自己做一個思想上的整理。

主要需要考慮的幾個方面

1.  網絡層和業務層的如何進行數據的交互
2.  如何提升網絡請求的安全性
3.  如何優化網絡請求

一、 網絡層和業務層的如何進行數據的交互

1.1 選擇集約型api請求,還是離散型api請求?

1.1.1 兩者的區別

集約型api,就是將所有的api請求都歸于一個apiManager去調配;而離散型則是根據不同的業務模塊,將對應的api請求各自創建apiManager進行管理。實際上離散型api就相對于對集約型api的分類,他的上一層就是一個總的apiManager作為父類。

補充一下其實我自己的理解,集約型一般是通過類方法的方式請求api,而離散型是通過實例方法完成。后者更容易針對一個task任務的起飛降落進行管控。(ps:我覺得這才是重點)

1.12 選擇哪一種?

離散型api。
1. 離散型api可以更方便地管理task任務的請求起飛和請求著陸。
2. AOP的處理方便。ios中主要體現在Method Swizzing
3. 離散型api可以根據需求增加api調用的靈活性。比如不需要進行page的管理,直接調用nextPage。

1.2 傳遞的數據是否需要Model化處理

不需要,直接傳遞json轉化后的數據即可(字典或者數組)。
CT老師的想法是view即便拿到了數據也不轉化成model,直接用一個轉化器Reformer去對數組/字典篩選展示的數據。具體要不要這樣操作,我覺得可以看看到底性能上有多少提升。
但如果沒什么區別,我覺得就沒必要了。比較久可讀性和開發效率來講model會更高。

原文中對數組的描述,說了5個點,我覺得可以總結為一下3點:
1.  減少不可復用的item對象(這個可以接受)
2.  數據的使用需要二次轉化。(不確定性能會差多少)
3. 同意api數據被不同view展示時,難以控制數據轉化的代碼,他們可能會在任何地方。(這個難以理解)

1.3 通過什么方式來傳遞數據

網絡層常用的3種數據傳值方法:Notification、Delegate、Bolck。
先說結果:如果是跨層訪問,如網絡狀態的切換,建議采用Notification(一般也只有這個會這樣操作)。其他的只能上一層或下一層交互的,使用Delegate完成,不建議使用Block

下面說說block和delegate的問題
1. 使用方便性
block方便,但delegate也不差。

2. 可讀性
block只能向上看,而不能向下看(查看哪些地方調用了該block)。

3. 對生命周期的影響
block會對捕捉的對象引用計數器+1,這樣會造成內存泄露(這個可以用weak解決)。但造成的問題是,blcok會延長對象的生命周期。
比如說在一個控制器中請求一個api,該api的block中訪問了self,在請求沒有著陸之前,該控制器的內存就無法被釋放。(當然你可以說主動調用task cancle來解決,那我沒話說)

二、提升網絡請求的安全性

主要考慮2點:

  1. 服務器如何辨別請求該api的客戶端是被認可的客戶端(防止對手爬api)
一般可以通過簽名的方式實現:
服務器提供一個密鑰,調用api時通過api名和參數和密鑰拼接成一個參數一起發給服務器,服務器獲取到了之后進過校對,判定是否來自認可的客戶端。

  1. 客戶端請求api時,如果保證傳輸數據的安全(運營商很喜歡往http請求中塞廣告)
HTTPS
這貨比http慢很多。
http耗時 = TCP3次握手
https耗時 = TCP3次握手 + SSL握手

三、網絡優化

api發起請求是通過3個步驟
1. 發起請求
2. DNS域名解析獲取ip
3. 根據http3次握手(https4次),連接建立

1.1 針對發起請求的優化

如果一個api對應的數據實效性夠長,可以把api名、參數拼接成一個字符串然后取MD5為key,存儲對應的數據。以后請求api可以先從本地獲取。api的請求可以先檢索本地數據。
PS:這里需要有一個本地數據的清理策略,可以根據數據的存儲量或者存儲時間來清理。

1.2 對重復請求的撤銷
如果在上一個請求還沒有結束的著陸的情況下,又發起了一個相同的請求,可以撤銷后面的請求。

2.1 域名解析api耗時的問題
直接采用ip訪問api

3.1 針對ip的優化
通過URLProtocol的優化,將Host轉化為可獲取到的速度最快的ip
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容