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