http://objccn.io/issue-6-4/html
CocoaPods 是開發 OS X 和 iOS 應用程序的一個第三方庫的依賴管理工具。利用 CocoaPods,能夠定義本身的依賴關係 (稱做 pods
),而且隨着時間的變化,以及在整個開發環境中對第三方庫的版本管理很是方便。git
CocoaPods 背後的理念主要體如今兩個方面。首先,在工程中引入第三方代碼會涉及到許多內容。針對 Objective-C 初級開發者來講,工程文件的配置會讓人很沮喪。在配置 build phases 和 linker flags 過程當中,會引發許多人爲因素的錯誤。CocoaPods 簡化了這一切,它可以自動配置編譯選項。github
其次,經過 CocoaPods,能夠很方便的查找到新的第三方庫。固然,這並非說你能夠簡單的將別人提供的庫拿來拼湊成一個應用程序。它的真正做用是讓你可以找到真正好用的庫,以此來縮短咱們的開發週期和提高軟件的質量。swift
本文中,咱們將經過分析 pod 安裝 (
pod install)
的過程,一步一步揭示 CocoaPods 背後的技術。xcode
CocoaPods是用 Ruby 寫的,並由若干個 Ruby 包 (gems) 構成的。在解析整合過程當中,最重要的幾個 gems 分別是: CocoaPods/CocoaPods, CocoaPods/Core, 和 CocoaPods/Xcodeproj (是的,CocoaPods 是一個依賴管理工具 -- 利用依賴管理進行構建的!)。緩存
編者注 CocoaPods 是一個 objc 的依賴管理工具,而其自己是利用 ruby 的依賴管理 gem 進行構建的ruby
這是是一個面向用戶的組件,每當執行一個 pod
命令時,這個組件都將被激活。該組件包括了全部使用 CocoaPods 涉及到的功能,而且還能經過調用全部其它的 gems 來執行任務。markdown
Core 組件提供支持與 CocoaPods 相關文件的處理,文件主要是 Podfile 和 podspecs。app
Podfile 是一個文件,用於定義項目所須要使用的第三方庫。該文件支持高度定製,你能夠根據我的喜愛對其作出定製。更多相關信息,請查閱 Podfile 指南。ide
.podspec
也是一個文件,該文件描述了一個庫是怎樣被添加到工程中的。它支持的功能有:列出源文件、framework、編譯選項和某個庫所須要的依賴等。
這個 gem 組件負責全部工程文件的整合。它可以對建立並修改 .xcodeproj
和 .xcworkspace
文件。它也能夠做爲單獨的一個 gem 包使用。若是你想要寫一個腳原本方便的修改工程文件,那麼可使用這個 gem。
pod install
命令當運行 pod install
命令時會引起許多操做。要想深刻了解這個命令執行的詳細內容,能夠在這個命令後面加上 --verbose
。如今運行這個命令 pod install --verbose
,能夠看到相似以下的內容:
$ pod install --verbose
Analyzing dependencies Updating spec repositories Updating spec repo `master` $ /usr/bin/git pull Already up-to-date. Finding Podfile changes - AFNetworking - HockeySDK Resolving dependencies of `Podfile` Resolving dependencies for target `Pods' (iOS 6.0) - AFNetworking (= 1.2.1) - SDWebImage (= 3.2) - SDWebImage/Core Comparing resolved specification to the sandbox manifest - AFNetworking - HockeySDK Downloading dependencies -> Using AFNetworking (1.2.1) -> Using HockeySDK (3.0.0) - Running pre install hooks - HockeySDK Generating Pods project - Creating Pods project - Adding source files to Pods project - Adding frameworks to Pods project - Adding libraries to Pods project - Adding resources to Pods project - Linking headers - Installing libraries - Installing target `Pods-AFNetworking` iOS 6.0 - Adding Build files - Adding resource bundles to Pods project - Generating public xcconfig file at `Pods/Pods-AFNetworking.xcconfig` - Generating private xcconfig file at `Pods/Pods-AFNetworking-Private.xcconfig` - Generating prefix header at `Pods/Pods-AFNetworking-prefix.pch` - Generating dummy source file at `Pods/Pods-AFNetworking-dummy.m` - Installing target `Pods-HockeySDK` iOS 6.0 - Adding Build files - Adding resource bundles to Pods project - Generating public xcconfig file at `Pods/Pods-HockeySDK.xcconfig` - Generating private xcconfig file at `Pods/Pods-HockeySDK-Private.xcconfig` - Generating prefix header at `Pods/Pods-HockeySDK-prefix.pch` - Generating dummy source file at `Pods/Pods-HockeySDK-dummy.m` - Installing target `Pods` iOS 6.0 - Generating xcconfig file at `Pods/Pods.xcconfig` - Generating target environment header at `Pods/Pods-environment.h` - Generating copy resources script at `Pods/Pods-resources.sh` - Generating acknowledgements at `Pods/Pods-acknowledgements.plist` - Generating acknowledgements at `Pods/Pods-acknowledgements.markdown` - Generating dummy source file at `Pods/Pods-dummy.m` - Running post install hooks - Writing Xcode project file to `Pods/Pods.xcodeproj` - Writing Lockfile in `Podfile.lock` - Writing Manifest in `Pods/Manifest.lock` Integrating client project
能夠上到,整個過程執行了不少操做,不過把它們分解以後,再看看,會發現它們都很簡單。讓咱們逐步來分析一下。
你是否對 Podfile 的語法格式感到奇怪過,那是由於這是用 Ruby 語言寫的。相較而言,這要比現有的其餘格式更加簡單好用一些。
在安裝期間,第一步是要弄清楚顯示或隱式的聲明瞭哪些第三方庫。在加載 podspecs 過程當中,CocoaPods 就創建了包括版本信息在內的全部的第三方庫的列表。Podspecs 被存儲在本地路徑 ~/.cocoapods
中。
CocoaPods 使用語義版本控制 - Semantic Versioning 命名約定來解決對版本的依賴。因爲衝突解決系統創建在非重大變動的補丁版本之間,這使得解決依賴關係變得容易不少。例如,兩個不一樣的 pods 依賴於 CocoaLumberjack 的兩個版本,假設一個依賴於 2.3.1
,另外一個依賴於 2.3.3
,此時衝突解決系統可使用最新的版本 2.3.3
,由於這個能夠向後與 2.3.1
兼容。
但這並不老是有效。有許多第三方庫並不使用這樣的約定,這讓解決方案變得很是複雜。
固然,總會有一些衝突須要手動解決。若是一個庫依賴於 CocoaLumberjack 的 1.2.5
,另一個庫則依賴於 2.3.1
,那麼只有最終用戶經過明確指定使用某個版原本解決衝突。
CocoaPods 執行的下一步是加載源碼。每一個 .podspec
文件都包含一個源代碼的索引,這些索引通常包裹一個 git 地址和 git tag。它們以 commit SHAs 的方式存儲在 ~/Library/Caches/CocoaPods
中。這個路徑中文件的建立是由 Core gem 負責的。
CocoaPods 將依照 Podfile
、.podspec
和緩存文件的信息將源文件下載到 Pods
目錄中。
每次 pod install
執行,若是檢測到改動時,CocoaPods 會利用 Xcodeproj gem 組件對 Pods.xcodeproj
進行更新。若是該文件不存在,則用默認配置生成。不然,會將已有的配置項加載至內存中。
當 CocoaPods 往工程中添加一個第三方庫時,不只僅是添加代碼這麼簡單,還會添加不少內容。因爲每一個第三方庫有不一樣的 target,所以對於每一個庫,都會有幾個文件須要添加,每一個 target 都須要:
.xcconfig
文件.xcconfig
文件prefix.pch
文件dummy.m
一旦每一個 pod 的 target 完成了上面的內容,整個 Pods
target 就會被建立。這增長了相同文件的同時,還增長了另外幾個文件。若是源碼中包含有資源 bundle,將這個 bundle 添加至程序 target 的指令將被添加到 Pods-Resources.sh
文件中。還有一個名爲 Pods-environment.h
的文件,文件中包含了一些宏,這些宏能夠用來檢查某個組件是否來自 pod。最後,將生成兩個承認文件,一個是 plist
,另外一個是 markdown
,這兩個文件用於給最終用戶查閱相關許可信息。
直到如今,許多工做都是在內存中進行的。爲了讓這些成果能被重複利用,咱們須要將全部的結果保存到一個文件中。因此 Pods.xcodeproj
文件被寫入磁盤,另外兩個很是重要的文件:Podfile.lock
和 Manifest.lock
都將被寫入磁盤。
這是 CocoaPods 建立的最重要的文件之一。它記錄了須要被安裝的 pod 的每一個已安裝的版本。若是你想知道已安裝的 pod 是哪一個版本,能夠查看這個文件。推薦將 Podfile.lock 文件加入到版本控制中,這有助於整個團隊的一致性。
這是每次運行 pod install
命令時建立的 Podfile.lock
文件的副本。若是你碰見過這樣的錯誤 沙盒文件與 Podfile.lock 文件不一樣步 (The sandbox is not in sync with the Podfile.lock)
,這是由於 Manifest.lock 文件和 Podfile.lock
文件不一致所引發。因爲 Pods
所在的目錄並不總在版本控制之下,這樣能夠保證開發者運行 app 以前都能更新他們的 pods,不然 app 可能會 crash,或者在一些不太明顯的地方編譯失敗。
若是你已經依照咱們的建議在系統上安裝了 xcproj,它會對 Pods.xcodeproj
文件執行一下 touch
以將其轉換成爲舊的 ASCII plist 格式的文件。爲何要這麼作呢?雖然在好久之前就不被其它軟件支持了,可是 Xcode 仍然依賴於這種格式。若是沒有 xcproj,你的 Pods.xcodeproj
文件將會以 XML 格式的 plist 文件存儲,當你用 Xcode 打開它時,它會被改寫,並形成大量的文件改動。
運行 pod install
命令的最終結果是許多文件被添加到你的工程和系統中。這個過程一般只須要幾秒鐘。固然沒有 Cocoapods 這些事也均可以完成。只不過所花的時間就不只僅是幾秒而已了。
CocoaPods 和持續集成在一塊兒很是融洽。雖然持續集成很大程度上取決於你的項目配置,但 Cocoapods 依然能很容易地對項目進行編譯。
若是 Pods 文件夾和裏面的全部內容都在版本控制之中,那麼你不須要作什麼特別的工做,就可以持續集成。咱們只須要給 .xcworkspace
選擇一個正確的 scheme 便可。
若是你的 Pods
文件夾不受版本控制,那麼你須要作一些額外的步驟來保證持續集成的順利進行。最起碼,Podfile
文件要放入版本控制之中。另外強烈建議將生成的 .xcworkspace
和 Podfile.lock
文件歸入版本控制,這樣不只簡單方便,也能保證所使用 Pod 的版本是正確的。
一旦配置完畢,在持續集成中運行 CocoaPods 的關鍵就是確保每次編譯以前都執行了 pod install
命令。在大多數系統中,例如 Jenkins 或 Travis,只須要定義一個編譯步驟便可 (實際上,Travis 會自動執行 pod install
命令)。對於 Xcode Bots,在書寫這篇文章時咱們還沒能找到很是流暢的方式,不過咱們正朝着解決方案努力,一旦成功,咱們將會當即分享。
CocoaPods 簡化了 Objective-C 的開發流程,咱們的目標是讓第三方庫更容易被發現和添加。瞭解 CocoaPods 的原理能讓你作出更好的應用程序。咱們沿着 CocoaPods 的整個執行過程,從載入 specs 文件和源代碼、建立 .xcodeproj
文件和全部組件,到將全部文件寫入磁盤。因此接下來,咱們運行 pod install --verbose
,靜靜觀察 CocoaPods 的魔力如何顯現。