6-2 深入理解 CocoaPods

CocoaPods 是開發(fā) OS X 和 iOS 應(yīng)用程序的一個第三方庫的依賴管理工具。利用 CocoaPods,可以定義自己的依賴關(guān)系 (稱作pods),并且隨著時間的變化,以及在整個開發(fā)環(huán)境中對第三方庫的版本管理非常方便。

CocoaPods 背后的理念主要體現(xiàn)在兩個方面。首先,在工程中引入第三方代碼會涉及到許多內(nèi)容。針對 Objective-C 初級開發(fā)者來說,工程文件的配置會讓人很沮喪。在配置 build phases 和 linker flags 過程中,會引起許多人為因素的錯誤。CocoaPods 簡化了這一切,它能夠自動配置編譯選項。

其次,通過 CocoaPods,可以很方便的查找到新的第三方庫。當(dāng)然,這并不是說你可以簡單的將別人提供的庫拿來拼湊成一個應(yīng)用程序。它的真正作用是讓你能夠找到真正好用的庫,以此來縮短我們的開發(fā)周期和提升軟件的質(zhì)量。

本文中,我們將通過分析pod 安裝 (pod install)的過程,一步一步揭示 CocoaPods 背后的技術(shù)。

核心組件

CocoaPods是用 Ruby 寫的,并由若干個 Ruby 包 (gems) 構(gòu)成的。在解析整合過程中,最重要的幾個 gems 分別是:CocoaPods/CocoaPods,CocoaPods/Core, 和CocoaPods/Xcodeproj(是的,CocoaPods 是一個依賴管理工具 -- 利用依賴管理進行構(gòu)建的!)。

編者注CocoaPods 是一個 objc 的依賴管理工具,而其本身是利用 ruby 的依賴管理 gem 進行構(gòu)建的

CocoaPods/CocoaPod

這是是一個面向用戶的組件,每當(dāng)執(zhí)行一個pod命令時,這個組件都將被激活。該組件包括了所有使用 CocoaPods 涉及到的功能,并且還能通過調(diào)用所有其它的 gems 來執(zhí)行任務(wù)。

CocoaPods/Core

Core 組件提供支持與 CocoaPods 相關(guān)文件的處理,文件主要是 Podfile 和 podspecs。

Podfile

Podfile 是一個文件,用于定義項目所需要使用的第三方庫。該文件支持高度定制,你可以根據(jù)個人喜好對其做出定制。更多相關(guān)信息,請查閱Podfile 指南

Podspec

.podspec也是一個文件,該文件描述了一個庫是怎樣被添加到工程中的。它支持的功能有:列出源文件、framework、編譯選項和某個庫所需要的依賴等。

CocoaPods/Xcodeproj

這個 gem 組件負責(zé)所有工程文件的整合。它能夠?qū)?chuàng)建并修改.xcodeproj和.xcworkspace文件。它也可以作為單獨的一個 gem 包使用。如果你想要寫一個腳本來方便的修改工程文件,那么可以使用這個 gem。

運行pod install命令

當(dāng)運行pod install命令時會引發(fā)許多操作。要想深入了解這個命令執(zhí)行的詳細內(nèi)容,可以在這個命令后面加上--verbose?,F(xiàn)在運行這個命令pod install --verbose,可以看到類似如下的內(nèi)容:


可以上到,整個過程執(zhí)行了很多操作,不過把它們分解之后,再看看,會發(fā)現(xiàn)它們都很簡單。讓我們逐步來分析一下。

讀取 Podfile 文件

你是否對 Podfile 的語法格式感到奇怪過,那是因為這是用 Ruby 語言寫的。相較而言,這要比現(xiàn)有的其他格式更加簡單好用一些。

在安裝期間,第一步是要弄清楚顯示或隱式的聲明了哪些第三方庫。在加載 podspecs 過程中,CocoaPods 就建立了包括版本信息在內(nèi)的所有的第三方庫的列表。Podspecs 被存儲在本地路徑~/.cocoapods中。

版本控制和沖突

CocoaPods 使用語義版本控制 - Semantic Versioning命名約定來解決對版本的依賴。由于沖突解決系統(tǒng)建立在非重大變更的補丁版本之間,這使得解決依賴關(guān)系變得容易很多。例如,兩個不同的 pods 依賴于 CocoaLumberjack 的兩個版本,假設(shè)一個依賴于2.3.1,另一個依賴于2.3.3,此時沖突解決系統(tǒng)可以使用最新的版本2.3.3,因為這個可以向后與2.3.1兼容。

但這并不總是有效。有許多第三方庫并不使用這樣的約定,這讓解決方案變得非常復(fù)雜。

當(dāng)然,總會有一些沖突需要手動解決。如果一個庫依賴于 CocoaLumberjack 的1.2.5,另外一個庫則依賴于2.3.1,那么只有最終用戶通過明確指定使用某個版本來解決沖突。

加載源文件

CocoaPods 執(zhí)行的下一步是加載源碼。每個.podspec文件都包含一個源代碼的索引,這些索引一般包裹一個 git 地址和 git tag。它們以 commit SHAs 的方式存儲在~/Library/Caches/CocoaPods中。這個路徑中文件的創(chuàng)建是由 Core gem 負責(zé)的。

CocoaPods 將依照Podfile、.podspec和緩存文件的信息將源文件下載到Pods目錄中。

生成 Pods.xcodeproj

每次pod install執(zhí)行,如果檢測到改動時,CocoaPods 會利用 Xcodeproj gem 組件對Pods.xcodeproj進行更新。如果該文件不存在,則用默認配置生成。否則,會將已有的配置項加載至內(nèi)存中。

安裝第三方庫

當(dāng) CocoaPods 往工程中添加一個第三方庫時,不僅僅是添加代碼這么簡單,還會添加很多內(nèi)容。由于每個第三方庫有不同的 target,因此對于每個庫,都會有幾個文件需要添加,每個 target 都需要:

一個包含編譯選項的.xcconfig文件

一個同時包含編譯設(shè)置和 CocoaPods 默認配置的私有.xcconfig文件

一個編譯所必須的prefix.pch文件

另一個編譯必須的文件dummy.m

一旦每個 pod 的 target 完成了上面的內(nèi)容,整個Podstarget 就會被創(chuàng)建。這增加了相同文件的同時,還增加了另外幾個文件。如果源碼中包含有資源 bundle,將這個 bundle 添加至程序 target 的指令將被添加到Pods-Resources.sh文件中。還有一個名為Pods-environment.h的文件,文件中包含了一些宏,這些宏可以用來檢查某個組件是否來自 pod。最后,將生成兩個認可文件,一個是plist,另一個是markdown,這兩個文件用于給最終用戶查閱相關(guān)許可信息。

寫入至磁盤

直到現(xiàn)在,許多工作都是在內(nèi)存中進行的。為了讓這些成果能被重復(fù)利用,我們需要將所有的結(jié)果保存到一個文件中。所以Pods.xcodeproj文件被寫入磁盤,另外兩個非常重要的文件:Podfile.lock和Manifest.lock都將被寫入磁盤。

Podfile.lock

這是 CocoaPods 創(chuàng)建的最重要的文件之一。它記錄了需要被安裝的 pod 的每個已安裝的版本。如果你想知道已安裝的 pod 是哪個版本,可以查看這個文件。推薦將 Podfile.lock 文件加入到版本控制中,這有助于整個團隊的一致性。

Manifest.lock

這是每次運行pod install命令時創(chuàng)建的Podfile.lock文件的副本。如果你遇見過這樣的錯誤沙盒文件與 Podfile.lock 文件不同步 (The sandbox is not in sync with the Podfile.lock),這是因為 Manifest.lock 文件和Podfile.lock文件不一致所引起。由于Pods所在的目錄并不總在版本控制之下,這樣可以保證開發(fā)者運行 app 之前都能更新他們的 pods,否則 app 可能會 crash,或者在一些不太明顯的地方編譯失敗。

xcproj

如果你已經(jīng)依照我們的建議在系統(tǒng)上安裝了xcproj,它會對Pods.xcodeproj文件執(zhí)行一下touch以將其轉(zhuǎn)換成為舊的 ASCII plist 格式的文件。為什么要這么做呢?雖然在很久以前就不被其它軟件支持了,但是 Xcode 仍然依賴于這種格式。如果沒有 xcproj,你的Pods.xcodeproj文件將會以 XML 格式的 plist 文件存儲,當(dāng)你用 Xcode 打開它時,它會被改寫,并造成大量的文件改動。

結(jié)果

運行pod install命令的最終結(jié)果是許多文件被添加到你的工程和系統(tǒng)中。這個過程通常只需要幾秒鐘。當(dāng)然沒有 Cocoapods 這些事也都可以完成。只不過所花的時間就不僅僅是幾秒而已了。

補充:持續(xù)集成

CocoaPods 和持續(xù)集成在一起非常融洽。雖然持續(xù)集成很大程度上取決于你的項目配置,但 Cocoapods 依然能很容易地對項目進行編譯。

Pods 文件夾的版本控制

如果 Pods 文件夾和里面的所有內(nèi)容都在版本控制之中,那么你不需要做什么特別的工作,就能夠持續(xù)集成。我們只需要給.xcworkspace選擇一個正確的 scheme 即可。

不受版本控制的 Pods 文件夾

如果你的Pods文件夾不受版本控制,那么你需要做一些額外的步驟來保證持續(xù)集成的順利進行。最起碼,Podfile文件要放入版本控制之中。另外強烈建議將生成的.xcworkspace和Podfile.lock文件納入版本控制,這樣不僅簡單方便,也能保證所使用 Pod 的版本是正確的。

一旦配置完畢,在持續(xù)集成中運行 CocoaPods 的關(guān)鍵就是確保每次編譯之前都執(zhí)行了pod install命令。在大多數(shù)系統(tǒng)中,例如 Jenkins 或 Travis,只需要定義一個編譯步驟即可 (實際上,Travis 會自動執(zhí)行pod install命令)。對于Xcode Bots,在書寫這篇文章時我們還沒能找到非常流暢的方式,不過我們正朝著解決方案努力,一旦成功,我們將會立即分享。

結(jié)束語

CocoaPods 簡化了 Objective-C 的開發(fā)流程,我們的目標是讓第三方庫更容易被發(fā)現(xiàn)和添加。了解 CocoaPods 的原理能讓你做出更好的應(yīng)用程序。我們沿著 CocoaPods 的整個執(zhí)行過程,從載入 specs 文件和源代碼、創(chuàng)建.xcodeproj文件和所有組件,到將所有文件寫入磁盤。所以接下來,我們運行pod install --verbose,靜靜觀察 CocoaPods 的魔力如何顯現(xiàn)。


翻譯作者:Programmer毒

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 項目組件化、平臺化是技術(shù)公司的共同目標,越來越多的技術(shù)公司推崇使用pod管理第三方庫以及私有組件,一方面使項目架構(gòu)...
    swu_luo閱讀 22,827評論 0 39
  • Ruby 安裝 要安裝cocospods 首先需要安裝ruby,可以先安裝xcode,再安裝macport ,最后...
    山天大畜閱讀 2,105評論 0 1
  • CocoaPods 是什么? CocoaPods 是一個負責(zé)管理 iOS 項目中第三方開源庫的工具。CocoaPo...
    朝洋閱讀 25,978評論 3 50
  • 站在街角, 我?guī)涎坨R 人 成片成流的 原來每個人真的是各有特色 面貌,表情,身材,穿著,走路的方式… 人熙熙攘攘...
    阿正的陽光閱讀 214評論 0 0
  • 火熱的天氣, 燃燒一顆浮躁的心。 立也不是,坐也不是, 不知疲倦的蒼蠅滿屋飛舞, 沒有一絲清靜。 雪糕,就是一個知...
    一只羊1237閱讀 169評論 0 2

友情鏈接更多精彩內(nèi)容