iOS基于中間層的路由跳轉(zhuǎn)方案

一. 總述
這個(gè)方案的最終目的很明確,就是要抽象出一個(gè)中間層來對(duì)紛亂的引用關(guān)系進(jìn)行統(tǒng)一的跳轉(zhuǎn)。模塊只和中間層耦合,模塊間解耦;中間層使用runtime的形式調(diào)用模塊的業(yè)務(wù)組件,不依賴具體的模塊代碼.

二. 業(yè)務(wù)場景
脫離業(yè)務(wù)需求的設(shè)計(jì)都是空中樓閣,下面將結(jié)合具體的業(yè)務(wù)場景進(jìn)行方案分析和設(shè)計(jì)。

下面是大多數(shù)app都會(huì)遇到的業(yè)務(wù)場景:

  • 啟動(dòng)開屏廣告是個(gè)運(yùn)營位置,需要任意跳轉(zhuǎn)
  • 輪播圖是個(gè)運(yùn)營位置,需要任意跳轉(zhuǎn)
  • webview中通過bridge,也存在任意跳轉(zhuǎn)原生的可能性
  • 模塊間各種push

簡單粗暴的方法,就是switch判斷類型,引入各種頭文件,直接跳轉(zhuǎn)。隨著業(yè)務(wù)膨脹,以下弊端會(huì)越來越明顯:

  • 沒有統(tǒng)一的跳轉(zhuǎn)管理,每塊業(yè)務(wù)都維護(hù)了自身的一套邏輯,使得跳轉(zhuǎn)邏輯四處散落;
  • 如果要新增一種跳轉(zhuǎn)類型,如1所述,必須要找到四處的跳轉(zhuǎn)邏輯,把可能的地方都加一遍,維護(hù)起來非常費(fèi)勁;
  • 模塊間文件直接引用,耦合嚴(yán)重。如果修改刪除了某個(gè)模塊間的某個(gè)文件,會(huì)直接影響到所有引用了他的文件;理想期望是獨(dú)立模塊可以編譯運(yùn)行,每個(gè)模塊可隨意插拔;
  • 模塊間的耦合導(dǎo)致模塊無法復(fù)用;理想期望是一個(gè)模塊復(fù)制到新項(xiàng)目時(shí),可以直接編譯運(yùn)行;

三.梳理分析
通過上述業(yè)務(wù)場景,最直觀的痛點(diǎn)的跳轉(zhuǎn)管理問題,但本質(zhì)上都是耦合的問題,是文件間的引用耦合。
要調(diào)用一個(gè)類的方法,import相關(guān)的頭文件,再根據(jù)頭文件暴露的api進(jìn)行調(diào)用,這再正常不過了。當(dāng)業(yè)務(wù)膨脹后,模塊內(nèi)可以直接耦合引用,但模塊間就必須想辦法解耦。
目前業(yè)內(nèi)有兩種主流方案:

  1. 以JLRoutes為代表的URLRoute方案:以URL為key,以待執(zhí)行的block為value,保存在一個(gè)全局map中,在內(nèi)存中常駐;
  2. Mediator中間人方案:把所有的調(diào)用都集合在一起,使用一個(gè)中間人管理。所有調(diào)用方都通過中間人調(diào)取另外一個(gè)模塊;

這兩種方案單獨(dú)來說都有各自的優(yōu)劣勢(shì):

  • URLRoute方案借鑒了web的思路,非常契合遠(yuǎn)程調(diào)用這種場景。但是在開發(fā)時(shí)本地原生調(diào)用時(shí),使用者會(huì)感到變扭。我們更習(xí)慣調(diào)方法,給方法賦值。在使用URLRoute時(shí),我們還需要多一步轉(zhuǎn)換邏輯,將方法調(diào)用轉(zhuǎn)換成URL形式。這既不方便,同樣存在漏洞。因?yàn)閁RL中只能攜帶常規(guī)數(shù)據(jù),無法把類似UIImage等格式的數(shù)據(jù)封裝在URL中。
  • Mediator方案相比起來對(duì)原生調(diào)用就非常友好,但當(dāng)遇見app://user/:userName這樣的跳轉(zhuǎn)需求時(shí),就顯得不那么契合。
    詳情的分析可以參考https://casatwy.com/iOS-Modulization.html.

四. 結(jié)合URLRoute和Mediator的跳轉(zhuǎn)方案

分析到這里,其實(shí)最后的方案已經(jīng)呼之欲出了。我們即想要URLRoute這種完美契合schema模型的遠(yuǎn)程調(diào)用體驗(yàn),也想要Mediator本地方法調(diào)用的體驗(yàn)。
1.png

方案如圖所示,具體demo在https://github.com/xuzhenhao/ZHMediator。下面將結(jié)合組件化的思路一起闡述整個(gè)方案如何落地。

  1. 模塊化拆分。
  • 首先要進(jìn)行模塊的劃分,只有模塊間的調(diào)用才會(huì)考慮這種方式,模塊內(nèi)的調(diào)用是允許相互間耦合的,因此合理的模塊劃分就很重要。
  • 暴露Target對(duì)象。Target對(duì)象暴露整個(gè)模塊對(duì)外提供的所有服務(wù),此外,因?yàn)镸ediator和Target是通過Runtime交互的,Target暴露的方法中接收的參數(shù)是一個(gè)字典,但在方法實(shí)現(xiàn)中負(fù)責(zé)將傳過來的字典還原成各個(gè)參數(shù),并調(diào)用該模塊具體的類和方法。
  • 編寫模塊的Mediator分類。如上所述,受限于runtime只能以字典形式傳一系列參數(shù),Mediator分類的職責(zé)就在于對(duì)外提供參數(shù)友好型的一系列方法,但在方法實(shí)現(xiàn)中包裝成字典形式。這里涉及到key的定義必須和Target中還原時(shí)的key定義一致,因此劃分給相同的開發(fā)維護(hù)。
  1. 遠(yuǎn)程調(diào)用
  • 配置URL解析規(guī)則。類似app://user/:userId/detail 這樣的URL,需要通過解析規(guī)則,解析出TargetName、ActionName、Params,交付給Mediator進(jìn)行處理。目前只是簡單基于JLRoutes的二次封裝,當(dāng)然這里可以根據(jù)需求,后續(xù)也能方便替換。這部分配置建議統(tǒng)一放在AppDelegete+Routes的分類中統(tǒng)一配置。

至此,核心部分就介紹完畢了。完整的demo可以在https://github.com/xuzhenhao/ZHMediator獲得。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 到今天已經(jīng)一周左右沒有寫簡書沒有投射了,今天終于重新歸來,能量補(bǔ)充好了。成長道路曲曲折折啊! 其實(shí)上周后來還不錯(cuò),...
    愛雯雯閱讀 195評(píng)論 0 0

友情鏈接更多精彩內(nèi)容