iOS應用模組化的思考及落地方案(二)模組化自動構建工具的使用

hard_man發表於2019-04-28

1.0 iOS模組化中的問題

前文已經介紹了模組化的流程及一些常見的問題,我們在這裡再次總結一下。

在工作中,當我們開始一個新專案的時候,最先考慮的就是模組化工作。

模組化工作的想法是很美好的,可是執行過程中會遇到很多的問題,而這些問題可能會讓我們在工作中舉步維艱。

  1. 工具使用問題。iOS的模組化一般會使用cocoapods工具,這個工具很強大,內容也很豐富,我們想要完成模組化工作,需要建立私有庫,編寫podspec檔案,處理資源,編寫Podfile檔案,建立本地依賴等等。讓團隊成員每個人都精通這個工具是不必要的。因此經常會在使用工具中遇到不易解決的問題,從而浪費大量的時間。

  2. xcode設定問題。xcode設定項多如牛毛,很多內容看起來並不直觀,需要我們去查閱官方文件來解決。而且這些設定數量多,使用的頻率又少,所以難免會出現這樣的情況:每個人都遇到的問題,然後各自去花時間解決,然後過段時間遇到相同的問題常常就忘記了,還要花時間去查閱解決,造成資源的重複浪費。

  3. 模組間依賴的問題,當你依賴的也是私有庫的其他模組(下文中稱為自有模組)時,開發中可能要同時修改多個模組,這樣就會出現在多個工程中切換的問題。

  4. 規範問題,每個人建立模組的方式可能都不同,包括工程結構,工程設定等等。這樣一來,不同的模組可能差異特別大,當跨模組開發或者程式碼交接的時候,可能就會出現難以解決的問題。

  5. 設定的變更修改都是手動修改,有時候難免會因為疏忽,而導致難以發現的錯誤,當需要處理的模組和依賴較多時,發生錯誤的概率也會增加。

2.0 編寫自動化工具

為了解決這些問題,讓團隊能夠將精力全部集中到業務開發中,特使用bash shell開發一個構建工具,用於自動化處理模組化的過程中遇到的設定及工具使用問題。

工具的地址如下:github.com/hardman/AWM…

使用這個自動化工具你將會獲得如下能力:

  1. 一條命令即可建立模組工程,建立.podspec及Podfile檔案,自動安裝依賴,工程預設使用靜態庫,支援Swift和OC
  2. 一條命令即可拉取之前開發的模組,並且安裝好所有依賴
  3. 一條命令即可自動打tag,自動更新.podspec檔案,將工程推送到pod伺服器
  4. 自有模組的列表,將會儲存在單獨git庫中,便於有依賴模組時,可動態載入
  5. 自有模組的依賴都通過.podspec檔案使用local path的方式安裝,這樣當被依賴的模組也需要修改時,不需要開啟多個工程

因此,使用這個自動化工具,你不需要了解cocoapods工具,也不需要處理任何工程和工具設定,可以將注意力都集中到業務開發中。

【注】工具使用靜態庫作為模組的輸出檔案。

3.0 工具的使用

3.1 基本使用步驟

  1. 將工程clone到本地目錄
  2. 開啟tools/config修改配置檔案
    • modulelistgitaddress.txt:新建一個git庫,並將地址儲存在這個檔案中,地址最好是以git@開頭。這個git庫用於儲存所有自有模組名稱及地址。
    • podspecsaddr.txt:再新建一個git庫,將地址儲存在這個檔案中,地址最好是git@開頭。這個git庫就是你的私有庫地址。
    • podspecsname.txt:為你的git庫取一個名字,儲存在這個檔案中
    • 上述3個檔案都只有一行
    • dependencypodrepos.txt:這個檔案儲存你的app依賴的其他pod repos,一般情況下保持預設即可,支援多行,每行儲存一個地址
    • 由於這些配置幾乎不會修改,考慮將這些檔案提交到你自己的git庫中
  3. 執行 ./create.sh -n=[模組名] -b=[bundle id] -t=[s|f|r] 即可建立工程
    • 指令碼執行過程中會要求輸入一些工程基本資訊及所依賴的模組,請認真輸入,不要遺漏
    • 建立的工程會自動開啟,並且可以直接執行
    • 建立好的模組檔案在:工程根目錄/modules
    • 例:./create.sh -n=HelloWorld -b=com.helloworld -t=s
  4. 模組開發完畢,需要將程式碼提交到develop分支,然後執行./push.sh [模組名] [tag]
    • 執行push.sh時,模組必須在develop分支上
    • 執行成功後,你的模組就已經提交成功,可以通過Podfile檔案引用了
    • 例:./push.sh HelloWorld 0.0.1
  5. 使用 ./pull.sh [模組名] 即可下載其他未同步到本地的自有模組
    • 執行成功後,會自動下載所有依賴的模組,並通過local path新增到模組依賴中
    • 例:./pull.sh HelloWorld

3.2 如何提升模組所依賴其他模組的版本號

有的時候,當前模組所依賴的模組版本升級了,需要修改當前模組的依賴檔案。 有2種方法:

  1. 直接修改檔案
    • 需要修改的檔案有2個,一個是檔案根目錄的dependency.txt檔案,檔案內記錄了當前模組依賴的自有模組
    • dependency.txt檔案記錄模組版本的格式是:每行一個模組;格式為:模組名@@版本號,版本號支援~>字首,不可帶空格
    • 另一個檔案是模組名.podspec檔案
    • 按照podspec檔案要求的格式去修改版本號
  2. 使用指令碼修改
    • 執行命令:./utils.sh [模組名] upgradedependency [依賴的模組名] [版本號]
    • 其中版本號可以為空
    • 例子:./utils.sh LoginModule upgradedependency AFNetworking 3.5.0
    • 例子:./utils.sh LoginModule upgradedependency AFNetworking
  3. 版本號可支援英文字元:a.b.c

3.3 如何在模組工程內使用Swift&OC混編

  1. 在module工程內建立OC的類檔案及swift檔案,假設OC類名為 TestOC,swift類名為TestSwift
  2. 讓OC能夠訪問Swift類
    • 只需要在TestOC.m中新增import。例:#import "模組名/模組名-Swift.h"
    • 另外需注意的是,TestSwift類必須是public並繼承自NSObject。
  3. 讓Swift能夠訪問OC類
    • 在 [模組名].h 這個檔案中引入你的標頭檔案。例:#import "TestOC.h"
    • xcode - build phases - [模組名].h 檔案必須在public區域

3.4 關於模組資原始檔的獲取

  1. 由於模組都是靜態庫,所以最終執行到app中後,每個模組的資原始檔(.xcassets, .xib, .png, .jpg, .jpeg, .gif, .txt, .plist, .bundle, .zip, .car)都是放到: "模組名.bundle"檔案中的,而這個bundle在main bundle的根目錄(這也是要求模組名防止重名的原因之一)
  2. 所以獲取圖片可以使用 UIImage.init(named: name, in: bundle, compatibleWith: nil) 方法
  3. 獲取其他檔案也需要指定bundle才可以
  4. 開發過程中,獲取任何資源都需要帶bundle,不能直接使用類似 UIImage.init(named:String)這種方法,即使是在模組工程內部的程式碼也不行
  5. 需要注意的是,靜態庫的單元測試target是無法獲取資源的

3.5 注意事項

  1. 模組名要防止重複,不但要防止同一個私有庫重複,也要防止與其他pod repo內的模組重複
  2. 依賴庫不可產生迴圈依賴,比如 A依賴B,B依賴C,C依賴A
  3. 每個模組都有一個develop分支,develop分支的程式碼總是與最新的tag保持一致。執行push命令時,程式碼總是在develop分支上
  4. 開發期間(整合測試前)總是依賴本地模組,每次總是在整合測試前,才會執行push.sh指令碼
  5. 如果當前的開發模組有修改,同時依賴的模組也有修改,則需要先push當前模組所依賴的模組,最後push當前模組。這時候可能需要使用 ./utils.sh [模組名] upgradedependency [依賴的模組名] [版本號] 命令修改模組所依賴的模組的版本號

--完--

  1. iOS應用模組化的思考及落地方案(一)模組的劃分及模組化工作流程
  2. iOS應用模組化的思考及落地方案(二)模組化自動構建工具的使用

相關文章