iOS應(yīng)用模塊化的思考及落地方案(二)模塊化自動(dòng)構(gòu)建工具的使用

1.0 iOS模塊化中的問(wèn)題

前文已經(jīng)介紹了模塊化的流程及一些常見(jiàn)的問(wèn)題,我們?cè)谶@里再次總結(jié)一下。

在工作中,當(dāng)我們開(kāi)始一個(gè)新項(xiàng)目的時(shí)候,最先考慮的就是模塊化工作。

模塊化工作的想法是很美好的,可是執(zhí)行過(guò)程中會(huì)遇到很多的問(wèn)題,而這些問(wèn)題可能會(huì)讓我們?cè)诠ぷ髦信e步維艱。

  1. 工具使用問(wèn)題。iOS的模塊化一般會(huì)使用cocoapods工具,這個(gè)工具很強(qiáng)大,內(nèi)容也很豐富,我們想要完成模塊化工作,需要建立私有庫(kù),編寫podspec文件,處理資源,編寫Podfile文件,建立本地依賴等等。讓團(tuán)隊(duì)成員每個(gè)人都精通這個(gè)工具是不必要的。因此經(jīng)常會(huì)在使用工具中遇到不易解決的問(wèn)題,從而浪費(fèi)大量的時(shí)間。

  2. xcode設(shè)置問(wèn)題。xcode設(shè)置項(xiàng)多如牛毛,很多內(nèi)容看起來(lái)并不直觀,需要我們?nèi)ゲ殚喒俜轿臋n來(lái)解決。而且這些設(shè)置數(shù)量多,使用的頻率又少,所以難免會(huì)出現(xiàn)這樣的情況:每個(gè)人都遇到的問(wèn)題,然后各自去花時(shí)間解決,然后過(guò)段時(shí)間遇到相同的問(wèn)題常常就忘記了,還要花時(shí)間去查閱解決,造成資源的重復(fù)浪費(fèi)。

  3. 模塊間依賴的問(wèn)題,當(dāng)你依賴的也是私有庫(kù)的其他模塊(下文中稱為自有模塊)時(shí),開(kāi)發(fā)中可能要同時(shí)修改多個(gè)模塊,這樣就會(huì)出現(xiàn)在多個(gè)工程中切換的問(wèn)題。

  4. 規(guī)范問(wèn)題,每個(gè)人建立模塊的方式可能都不同,包括工程結(jié)構(gòu),工程設(shè)置等等。這樣一來(lái),不同的模塊可能差異特別大,當(dāng)跨模塊開(kāi)發(fā)或者代碼交接的時(shí)候,可能就會(huì)出現(xiàn)難以解決的問(wèn)題。

  5. 設(shè)置的變更修改都是手動(dòng)修改,有時(shí)候難免會(huì)因?yàn)槭韬?,而?dǎo)致難以發(fā)現(xiàn)的錯(cuò)誤,當(dāng)需要處理的模塊和依賴較多時(shí),發(fā)生錯(cuò)誤的概率也會(huì)增加。

2.0 編寫自動(dòng)化工具

為了解決這些問(wèn)題,讓團(tuán)隊(duì)能夠?qū)⒕θ考械綐I(yè)務(wù)開(kāi)發(fā)中,特使用bash shell開(kāi)發(fā)一個(gè)構(gòu)建工具,用于自動(dòng)化處理模塊化的過(guò)程中遇到的設(shè)置及工具使用問(wèn)題。

工具的地址如下:https://github.com/hardman/AWModularization

使用這個(gè)自動(dòng)化工具你將會(huì)獲得如下能力:

  1. 一條命令即可創(chuàng)建模塊工程,創(chuàng)建.podspec及Podfile文件,自動(dòng)安裝依賴,工程默認(rèn)使用靜態(tài)庫(kù),支持Swift和OC
  2. 一條命令即可拉取之前開(kāi)發(fā)的模塊,并且安裝好所有依賴
  3. 一條命令即可自動(dòng)打tag,自動(dòng)更新.podspec文件,將工程推送到pod服務(wù)器
  4. 自有模塊的列表,將會(huì)保存在單獨(dú)git庫(kù)中,便于有依賴模塊時(shí),可動(dòng)態(tài)加載
  5. 自有模塊的依賴都通過(guò).podspec文件使用local path的方式安裝,這樣當(dāng)被依賴的模塊也需要修改時(shí),不需要打開(kāi)多個(gè)工程

因此,使用這個(gè)自動(dòng)化工具,你不需要了解cocoapods工具,也不需要處理任何工程和工具設(shè)置,可以將注意力都集中到業(yè)務(wù)開(kāi)發(fā)中。

【注】工具使用靜態(tài)庫(kù)作為模塊的輸出文件。

3.0 工具的使用

3.1 基本使用步驟

  1. 將工程clone到本地目錄
  2. 打開(kāi)tools/config修改配置文件
    • modulelistgitaddress.txt:新建一個(gè)git庫(kù),并將地址保存在這個(gè)文件中,地址最好是以git@開(kāi)頭。這個(gè)git庫(kù)用于保存所有自有模塊名稱及地址。
    • podspecsaddr.txt:再新建一個(gè)git庫(kù),將地址保存在這個(gè)文件中,地址最好是git@開(kāi)頭。這個(gè)git庫(kù)就是你的私有庫(kù)地址。
    • podspecsname.txt:為你的git庫(kù)取一個(gè)名字,保存在這個(gè)文件中
    • 上述3個(gè)文件都只有一行
    • dependencypodrepos.txt:這個(gè)文件保存你的app依賴的其他pod repos,一般情況下保持默認(rèn)即可,支持多行,每行保存一個(gè)地址
    • 由于這些配置幾乎不會(huì)修改,考慮將這些文件提交到你自己的git庫(kù)中
  3. 執(zhí)行 ./create.sh -n=[模塊名] -b=[bundle id] -t=[s|f|r] 即可創(chuàng)建工程
    • 腳本執(zhí)行過(guò)程中會(huì)要求輸入一些工程基本信息及所依賴的模塊,請(qǐng)認(rèn)真輸入,不要遺漏
    • 創(chuàng)建的工程會(huì)自動(dòng)打開(kāi),并且可以直接執(zhí)行
    • 創(chuàng)建好的模塊文件在:工程根目錄/modules。
    • 例:./create.sh -n=HelloWorld -b=com.helloworld -t=s
  4. 模塊開(kāi)發(fā)完畢,需要將代碼提交到develop分支,然后執(zhí)行./push.sh [模塊名] [tag]
    • 執(zhí)行push.sh時(shí),模塊必須在develop分支上
    • 執(zhí)行成功后,你的模塊就已經(jīng)提交成功,可以通過(guò)Podfile文件引用了
    • 例:./push.sh HelloWorld 0.0.1
  5. 使用 ./pull.sh [模塊名] 即可下載其他未同步到本地的自有模塊
    • 執(zhí)行成功后,會(huì)自動(dòng)下載所有依賴的模塊,并通過(guò)local path添加到模塊依賴中
    • 例:./pull.sh HelloWorld

3.2 如何提升模塊所依賴其他模塊的版本號(hào)

有的時(shí)候,當(dāng)前模塊所依賴的模塊版本升級(jí)了,需要修改當(dāng)前模塊的依賴文件。
有2種方法:

  1. 直接修改文件
    • 需要修改的文件有2個(gè),一個(gè)是文件根目錄的dependency.txt文件,文件內(nèi)記錄了當(dāng)前模塊依賴的自有模塊。
    • dependency.txt文件記錄模塊版本的格式是:每行一個(gè)模塊;格式為:模塊名@@版本號(hào),版本號(hào)支持~>前綴,不可帶空格
    • 另一個(gè)文件是模塊名.podspec文件
    • 按照podspec文件要求的格式去修改版本號(hào)
  2. 使用腳本修改
    • 執(zhí)行命令:./utils.sh [模塊名] upgradedependency [依賴的模塊名] [版本號(hào)]
    • 其中版本號(hào)可以為空
    • 例子:./utils.sh LoginModule upgradedependency AFNetworking 3.5.0
    • 例子:./utils.sh LoginModule upgradedependency AFNetworking
  3. 版本號(hào)可支持英文字符:a.b.c

3.3 如何在模塊工程內(nèi)使用Swift&OC混編

  1. 在module工程內(nèi)創(chuàng)建OC的類文件及swift文件,假設(shè)OC類名為 TestOC,swift類名為TestSwift
  2. 讓OC能夠訪問(wèn)Swift類
    • 只需要在TestOC.m中添加import。例:#import "模塊名/模塊名-Swift.h"
    • 另外需注意的是,TestSwift類必須是public并繼承自NSObject。
  3. 讓Swift能夠訪問(wèn)OC類
    • 在 [模塊名].h 這個(gè)文件中引入你的頭文件。例:#import "TestOC.h"。
    • xcode - build phases - [模塊名].h 文件必須在public區(qū)域

3.4 關(guān)于模塊資源文件的獲取

  1. 由于模塊都是靜態(tài)庫(kù),所以最終運(yùn)行到app中后,每個(gè)模塊的資源文件(.xcassets, .xib, .png, .jpg, .jpeg, .gif, .txt, .plist, .bundle, .zip, .car)都是放到: "模塊名.bundle"文件中的,而這個(gè)bundle在main bundle的根目錄(這也是要求模塊名防止重名的原因之一)
  2. 所以獲取圖片可以使用 UIImage.init(named: name, in: bundle, compatibleWith: nil) 方法
  3. 獲取其他文件也需要指定bundle才可以
  4. 開(kāi)發(fā)過(guò)程中,獲取任何資源都需要帶bundle,不能直接使用類似 UIImage.init(named:String)這種方法,即使是在模塊工程內(nèi)部的代碼也不行
  5. 需要注意的是,靜態(tài)庫(kù)的單元測(cè)試target是無(wú)法獲取資源的

3.5 注意事項(xiàng)

  1. 模塊名要防止重復(fù),不但要防止同一個(gè)私有庫(kù)重復(fù),也要防止與其他pod repo內(nèi)的模塊重復(fù)
  2. 依賴庫(kù)不可產(chǎn)生循環(huán)依賴,比如 A依賴B,B依賴C,C依賴A
  3. 每個(gè)模塊都有一個(gè)develop分支,develop分支的代碼總是與最新的tag保持一致。執(zhí)行push命令時(shí),代碼總是在develop分支上
  4. 開(kāi)發(fā)期間(集成測(cè)試前)總是依賴本地模塊,每次總是在集成測(cè)試前,才會(huì)執(zhí)行push.sh腳本
  5. 如果當(dāng)前的開(kāi)發(fā)模塊有修改,同時(shí)依賴的模塊也有修改,則需要先push當(dāng)前模塊所依賴的模塊,最后push當(dāng)前模塊。這時(shí)候可能需要使用 ./utils.sh [模塊名] upgradedependency [依賴的模塊名] [版本號(hào)] 命令修改模塊所依賴的模塊的版本號(hào)

--完--

  1. iOS應(yīng)用模塊化的思考及落地方案(一)模塊的劃分及模塊化工作流程
  2. iOS應(yīng)用模塊化的思考及落地方案(二)模塊化自動(dòng)構(gòu)建工具的使用
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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