iOS之CocoaPods二进制化的实现方案
生活随笔
收集整理的這篇文章主要介紹了
iOS之CocoaPods二进制化的实现方案
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
背景
- 隨著公司業務規模的增長,iOS 客戶端的代碼量也越來越大,編譯一次項目的時間也越來越長。那么減少編譯時間成了一個不得不面對的問題;
- 隨著越來越多方便的第三方組件,現在開發App基本十多個第三方依賴以上。沒有build cache 或者打正式包的時候,每次基本耗時10分鐘以上;
- 現有的二進制方案如 Carthage、Rome 等都是在本地生成 framework,沒法實現“一次編譯,處處使用”的目標;
- 主要原因是需要編譯大量源文件(大概分為 App 和 Cocoapods 依賴庫),所以把可抽離代碼編譯好,再去引用就能減少源文件編譯時間;
- 為了實現這個目標,就需要一個人或者一個 CI Job,把編譯好的二進制產物上傳到某個的地方,集中化地管理這些二進制形式的依賴。然后在每個人 pod install 的時候,檢查該 pod 版本對應的二進制是否存在,如果有就使用,沒有就繼續采用源碼的方式依賴;
- 這個方案隱藏了許多細節,比如到底應該如何集中管理這些 pod,如何知道對應的版本是否存在,如何在 pod install 的時候動態地把這些 pod 從源碼形式的依賴換成二進制形式的依賴等;
- 整個流程涉及生產方(產生二進制)和消費方(使用二進制)。
思路流程
一、產生二進制
① 代碼結構
- 產生二進制的流程在一個 CI Job 中,每隔一段時間,它會同步主倉庫最新的 dev 分支,然后運行管理此環節的工具,Platypus;
- 結構如下:
- 說明:
- config.yml 是與工程相關聯的配置,其中包含了需要二進制化的名單(pod_names),project 文件相關信息,以及工程初始化的 action(prebuild_action)等等。
- specs_repo 是私有的 podspec 倉庫,需要單獨創建,負責集中管理已經二進制好的 pod 信息。
② 具體流程
- (a)對于大多數項目來說是 pod install,但如果在不改變 podfile 原有寫法的基礎上實現此套方案,需要把使用 patch 過后的 pod install 方式。
- (b)白名單存在的意義有兩點:
- 一是有些 pod 本來就是二進制好了的;
- 二是某些 pod 因為頭文件沒有用 < > 的方式引用在目前階段沒法二進制,否則就會因為找不到頭文件編譯失敗;
- ( c )模擬器和真機的版本都需要編譯,最終使用 lipo 把兩份二進制合并到一個 .framework 中。如果 pod 中包含 Swift 代碼,需要把模擬器和真機的編譯產物中的 swiftdoc 和 swiftmodule 都合并到一個文件夾中。由于 Swift 版本的原因,由舊版 Xcode 編譯生成 Swift 二進制是無法在新版 Xcode 中使用的;
- (f)通過 CocoaPods 中的 Analyzer 調用 analyzer.analyze.specifications,可以獲取當前項目所有依賴 pod 的 podspecs,具體操作可以參考該文章:分析使用 CocoaPods 項目的依賴;關于如何編輯 podspec,可以使用這個 gem。編輯的內容包括刪掉 source_files 字段,把 vendored_frameworks 字段指向 .framework, source 指向上傳生成的 URL, resources 指向對應 .framework 中的資源等。保存后,作為二進制時依賴使用的 podspec;
- (g)這一步是為了把項目中依賴的 pod 版本與二進制化后的版本建立起聯系。因為項目中依賴的引用方式五花八門,有用 CocoaPods Master Repo 中版本號的,有用 git tag 的,也有用 git commmit 的,針對不同的引用方式,都要有對應的匹配規則;
③ 示例說明
- (g) 示例說明:比如有一個使用 tag 方式引用的組件,把它的 tag 號后面加上 -yang-static 作為它在私有 Specs 倉庫中的版本號,它在 podfile 中的 external_source 作為 summary 字段,同時確保唯一性。這里的映射關系只要能一一對應起來,隨便怎么建立都好,如下:
- 所以它被改完版本號后 poddpec 會變成如下樣式:
- (h) Specs 倉庫目錄結構如下所示,目錄均為手動創建,沒有使用 CocoaPods 提供的方式更新:
二、使用二進制
- 在觸發 pod install 過程之前,需要在本地把私有 Specs 倉庫更新到最新,pod repo update xxx;
- 接下來就是 patch pod install 替換依賴的過程,在不更改 podfile 的情況下,只能模仿 pod install 的過程,自己創建一個腳本來替代這個操作。整個過程不復雜,可以參考下面這一段帶注釋的代碼:
局限
- 需要自定義 pod install 過程,同時修改某些 CocoaPods 中的私有屬性;
- 最終的 binary size 會比使用源碼的時候大一點,不建議最終上傳 Store 的時候使用;
- 缺少一個驗證的機制,如果已發布的二進制包不能被項目正常引用,那么會導致所有人的編譯失敗;
- 由于工程采用的是全部靜態庫依賴的形式,所以在二進制和源碼切換的過程中會對 project 文件產生更改。
步驟總結
① 打包第三方源碼
- git clone各種組件源碼庫;
- 腳本打包:
- tag拉分支, 并切換(打包之后刪除, 再回去master);
- 使用pod gen根據podsec創建工程;
- xcodebuild打包framework(真機和模擬器);
- 合并真機和模擬器的framework;
- 實踐的時候會發現有些庫是不能通用一個腳本的;
- 上傳framework(用了binary-server管理);
② 二進制的podsec上傳到私有的repo
- 使用pod bin spec create創建二進制版本的podsec;
- 有subsec的會要求提供template;
- 某些平臺要求版本會低于8, 因為是使用framework, 需要平臺版本需要改為8以上;
- 上傳生成的podsec;
③ 使用
- 在Podfile加上source {私有repo},然后再加一個官方的repo(例如: source ‘https://cdn.cocoapods.org/’)。
- 官方的一定要加在后面,有相同的庫會根據source的順序獲取依賴,想切回源碼注釋私有庫那一行就好了(因為只是簡單的一個私有二進制repo)。
輔助工具
- cocoapods-bin
- binary-server
總結
以上是生活随笔為你收集整理的iOS之CocoaPods二进制化的实现方案的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【数据结构与算法】之重复的DNA序列的算
- 下一篇: Swift之深入解析“对象”的底层原理