利用 CocoaPod 和 Git 管理元件中的一些細節梳理

syik發表於2017-12-19

CocoaPod 與 Git 元件化相關細節

前言

隨著專案的發展, 元件化幾乎是一個必然的過程, 而使用 Git + CocoaPod 來管理元件是目前業界主流方式.

使用 Pod 來管理元件的優勢是非常明顯的, 網路上一些文章說的非常清楚, 個人最看重的是以下三點:

  1. 從根本上解決混亂引用導致的強耦合問題.
  2. 每個 Pod 可以獨立維護, 獨立單元測試, 單獨走 Git Flow 流程.
  3. 穩定的元件可以打包成靜態庫加快編譯速度.

但也需要知道, 元件化會帶來一系列缺點, 而這些缺點你在網上一般找不到:

  1. 學習成本, 使用 Pod 與 Git 來管理元件可能會遇到一般使用 Pod 沒有遇到的各種問題, 這種採坑成本是不能忽略的.
  2. 使用 Pod 管理元件無疑會拉長每個開發人員的開發流程, 提高開發成本.
  3. 當元件的邊界不清晰或者元件還沒有非常穩定的時候, 反覆修改真的很浪費時間.
  4. 元件化依賴很好的 App 架構, 開發人員也需要有一定的架構思想, 什麼時候需要通過路由轉發訊息, 什麼時候做成獨立SDK, 層級之間的依賴, 都是需要思考的問題.
  5. 元件化之後, 每次合併程式碼衝突是亂七八糟, 往往一個 pod install 便帶來幾百個衝突, 適應並解決這種問題也是一種成本.
  6. 開發的元件一定要足夠封裝足夠聚合, 否則 Pod 與主工程中各種強依賴耦合是災難性的.

雖然元件化有種種不是, 但就像一個公司大了, 必須要有各種規範流程一樣, App大了, 開發人員多了, 元件化就如同 Git Flow 流程一樣, 麻煩但免去了很多問題.

一些檔案

元件化涉及到的東西還真不少, 以下會提到一些檔案, 可能你已經很熟悉, 但使用 Cocoapod 管理元件之後, 你將於他們打交道的更多, 下面記錄一些與之相關的細節.

podfile:

都知道這個檔案的作用, 如果你只用 pod 管理第三方庫 , 你可以直接使用一個普通模板 podfile, 新增第三方庫, 安裝即可, 但管理元件則需要對這個更熟悉, 這是管理元件的根本, 以下說說一些注意點:

  1. use_frameworks!: 通個關鍵詞生成的是 framework 而不是靜態庫, 很直觀的就是 podfile 中加上這個, 在主工程中使用<>引用就要使用路徑, 不加則可以直接引用標頭檔案.
  2. inhibit_all_warnings!: 隱藏所有 pod 中的告警, 這個挺有用的, 加快編譯速度.
  3. 所有的 pod 都須指向 tag, 可以避免很多問題.
  4. source: 指定源, 第一個源應該是私有源, 後面才是官方源, 這樣若出現同名的 pod 會優先載入私有源中的, 方便映象第三方庫.
  5. def end語法: 用法很簡單, 就像巨集命令一樣, 但不支援駝峰標識.
  6. :configurations = 'Debug': 只在 debug 環境載入, 對應的關鍵詞是 'Release'.
  7. 每個元件一定要寫好註釋, 否則你同事看到的時候一定是懵逼的.
podfile.lock:

當我們執行 pod install 命令時, 工程中的 pod 就會更新到 podfile.lock 中的版本, 這個是讓我們在多人協作中避免第三方庫的版本不同的檔案, 但是不可避免的我們元件化之後會執行 pod update, 而每次 pod update 都會更新這個檔案, 所以這個檔案的作用便顯得有些雞肋了, 也正是因為這樣, podfile 中的各個 pod 應該指明 tag, 否則便是災難. 而且某些特殊的需求, 我們可能會需要切換 pod 的 tag, 也因這個檔案的存在, 使用 pod install 便會報錯, 只能使用 pod update.

manifest.lock:

可以簡單的理解為我們在本地執行一次 pod install 後生成的當前Podfile的狀態的表徵檔案, 一般用來校驗與 podfile.lock 是否一致.

xcconfig:

儲存每一個 pod 的工程配置檔案, 這個檔案很容易在合併程式碼時衝突, 一般可以忽略, pod install 即會重新生成.

project.pbxproj:

記錄工程檔案結構及位置的檔案, 不論有新增、移動或者刪除都會改變這個檔案, 所以這個是必定會衝突的檔案, 再配合上海量的 xcconfig 檔案變動, 讓合併程式碼變得更加困難, 一般的做法是以他人的版本解決問題, 對於主工程中的檔案, 缺少的重新 add file, 對於 pod 中的檔案, 直接 pod install, 再合併.

podspec:

每一個 pod 的配置檔案, 也是元件化的核心檔案, 我們建立的私有源或者官方源本質上就是一個個 pod 名字命名的資料夾, 子資料夾為各個版本號, 最內層就只有一個 podspec 檔案, 這個也是最容易出問題的檔案, 這個檔案的配置方法就不說了, 下面說說這個檔案中的注意點:

  1. version 問題, 一般來說, 這裡的 version 要等於 git 上的 tag 值.
  2. source_files 為原始檔.
  3. public_header_files 為開放的標頭檔案.
  4. resources 為資源路徑.
  5. frameworks 依賴的庫, 一般為系統的庫例如 AVFoundation、UIKit等.
  6. library 依賴的靜態庫, 比如 resolv、c++.
  7. vendored_frameworks pod 中 .framework 檔案.
  8. vendored_libraries pod 中的.a 檔案
  9. dependency 依賴的元件, 會從 podfile 中的 source 去尋找相關 pod, 建議在 podspec 中不要指定版本號, podfile 中統一指定.
  10. pod_target_xcconfig, 工程中配置的鍵值對.
  11. subspec, 子 pod, subspec 影響整合後的資料夾結構, 但不要層級太多, 也不要劃分太細, 非常影響編譯速度, 另外 subspec 之間的依賴不是資料夾依賴, 而是 superspec/subspec 這種形式.

一些操作

上面說了一些檔案及其中的細節, 下面說一下常用的操作.

pod lib lint 與 pod spec lint

前者為驗證遠端倉庫與本地倉庫, 後者為僅驗證本地倉庫, 有時候會出現只有一個能通過, 那表明遠端倉庫與本地倉庫沒有完全對應. 常用的引數:

  1. 允許告警 --allow-warnings.
  2. 該 pod 有使用靜態庫 --use-libraries.
  3. 列印詳細log --verbose.
  4. 自定義源 --source 源地址.
pod repo push 源的地址 podspec檔案

將 podspec 檔案 push 到私有源中. 過程中會經過 pod lib lint 驗證, 後面可以接驗證相同引數.

pod cache clean --all

清除 pod 相關快取, 若遇到一些快取相關的錯誤可以使用, 同時可以使用 pod repo remove 源名稱, 刪除相關本地倉庫.

pod package podspec檔案 --foce / pod package podspec檔案 --library --force

利用 pod package 打包靜態庫. 前者為 .framework, 後者為 .a 檔案.

tag 流程

打 tag 在元件化中是用的最多的流程, 雖然已經有 jinkins 這種工具讓這一步自動實現, 但我們也不能忘了手動 tag 的流程.

首先更新 pod 中的檔案, 及 podspec, 在示例程式中無錯誤後, podspec 中的 version 改為更大的版本號. 操作 git:

  1. git add .
  2. git commit -m '描述'
  3. git push
  4. git tag -a '版本號' -m '描述'
  5. git push --tags

再將 podspec 利用上面 repo push 命令推到私有源, podfile 修改對應版本號, pod update 對應pod, 完成了版本的升級. 值得注意的是 git 的 tag 不要刪除, 否則會出現一些快取問題.

待續....

相關文章