Cocoapods是 OS X 和 iOS 下的一個第三方庫管理工具。你能使用CocoaPods添加被稱作“Pods”的依賴庫,並輕松管理它們的版本,而不用考慮當前的時間和開發環境。
Cocoapods意義體現在兩個方面。首先,引入第三方庫無可避免地要進行各種各樣的配置。對於Objective-C的初級開發者來說,項目配置可是一件艱巨的任務。在配置編譯階段和鏈接器選項的過程中,極有可能引入許多人為的錯誤。而CocoaPods簡化了這一切,它能自動配置編譯選項,拯救了開發者。
其次,使用CocoaPods可以很方便地查找新的第三方庫。當然,這可不是說讓你七拼八湊別人代碼而開發出一個“移栽”應用。而是讓你找到真正好用的庫,縮短你的開發周期,提升你的代碼質量。
接下來,我們將通過分析pod安裝的過程,一步步揭示CocoaPods背后的技術。
核心組件
CocoaPods是用ruby寫的,並划分成了若干個Gem包。CocoaPods在解析執行過程中最重要的幾個包的路徑分別是:CocoaPods/CocoaPods、 CocoaPods/Core 和 CocoaPods/Xcodeproj。
CocoaPods / CocoaPod
這是面向用戶的組件,每當你執行一個pod命令時,這個組件將被激活。它包括了所有實用CocoaPods的功能,並且還能調用其他gem包來執行任務。
CocoaPods / Core
Core gem提供了與CocoaPods相關的文件(主要是Podfile和podspecs)的處理。
Podfile
Podfile用於配置項目所需要的第三方庫。它能被高度定制,所以你可以盡可能地給它添加你想要的特性。如果您還想對Podfile了解更多的話,請查看Podfile指南(地址 http://guides.cocoapods.org/syntax/podfile.html)。
Podspec
.podspec文件描述了一個庫將怎樣被添加進工程中。.podspec文件可以標識該第三方庫所需要的源碼文件、依賴庫、編譯選項,以及其他第三方庫需要的配置。
CocoaPods / Xcodeproj
這個包負責工程文件直接關系的處理。它能創建以及修改.xcodeproj文件和.xcworkspace文件。它也可以作為一個獨立的包使用,當你要編寫修改項目文件的腳本時,可以考慮使用CocoaPods/Xcodeproj。
運行 pod install 命令
pod install的執行引發了很多操作。了解底層運行過程最簡單的方式就是給pod install語句添加 –verbose 參數。現在,運行
1
|
pod
install
--verbose
|
將會出現以下執行結果:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
|
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文件
你是否吐槽過Podfile的語法太過詭異,其實這是ruby的語法而不是OC。相較而言,Podfile要比現有的其他格式更加簡單好用一些。
安裝的第一步是要弄清楚哪些第三方庫被顯式或隱式地聲明了。CocoaPods加載podspecs文件時,獲取了第三方庫的名稱及版本列表。Podsspecs文件存儲在本地,路徑為~/.cocoapods。
版本控制和沖突
CocoaPods使用語義版本命名約定來解決對版本的依賴。由於沖突解決系統建立在非重大更改的補丁版本之間,這使得解決依賴關系要容易得多。舉個栗子,兩個完全不同的第三方庫同時依賴CocoaLumberjack。它們其中一個依賴的版本是2.3.1,而另一個則為2.3.3,解析器可以自動使用較新的版本,在這里則是2.3.3,因為這可以與2.3.1向后兼容。
但這並不總是有效。有許多第三方庫還並不支持這個約定,這讓解決方案變得非常復雜。
當然,總是會有一些沖突需要手工解決。如果一個第三方庫依賴CocoaLumberjack 1.2.5,而另一個依賴CocoaLumberjack 2.3.1,最后只能靠調用這兩個第三方庫的用戶來手動地決定CocoaLumberjack的版本了。
加載源碼
CocoaPods執行的下一個步驟是加載源代碼。每個.podspec文件都包含了源代碼的索引,這些索引一般指向了一個git地址或者git tag。它們以commit SHA碼的方式存儲在 ~/Library/Caches/CocoaPods中。而在這些路徑中創建文件則由 Core 包負責。
源代碼將依照Podfile、.podspec和緩存文件的信息下載到相應的第三方庫路徑。
生成Pods.xcodeproj
每次pod install 執行后並且檢測到改動時,Pods.xcodeproj文件將唄Xcodeproj gem更新。如果Pods.xcodeproj文件不存在,則會以默認配置生成,若已存在,則Pods.xcodeproj會使用現有的配置。
安裝第三方庫
當Cocoapods向項目中增加了一個第三方庫的時候,不僅僅是將添加代碼這么簡單。由於每個第三方庫有不同的target,所以每次添加第三方庫時,都只有幾個文件被添加。每個源代碼都需要:
- 一個包含編譯選項的.xcconfig文件
- 一個同時擁有編譯設置和CocoaPods默認配置的私有.xcconfig文件
- 編譯所必須的prefix.pch文件
- 另一個編譯必須的文件dummy.m
一旦每個pod的target都完成了以上步驟,整個Pods的Target就會被創建。這增加了相同的文件,與另外幾個。如果有源代碼中包含了資源bundle,向app的target中添加bundle的方式將寫入Pods-Resources.sh。還有一個叫Pods-environment.h的文件,文件中含有許多檢查組件是否來自pod的宏定義。最后,將生成兩個確認文件,一個.plist文件,一個用於給用戶查閱許可信息的markdown文件。
寫入到磁盤
直到現在,許多已完成的過程都使用的是內存中的對象。為了讓這些過程的結果可重復被使用,我們需要將所有結果都記錄在一個文件中。所以Pods.xcodeproj和另外兩個非常重要的文件:Podfile.lock和Manifest.lock都將被寫入磁盤。
Podfile.lock
這是CocoaPods創建的最重要的文件之一。它記錄了需要被安裝的pod的每個已安裝的版本。如果你想知道已安裝的pod是哪個版本,可以查看這個文件。推薦將Podfile.lock文件加入到版本控制中,這有助於整個團隊的一致性。
Manifest.lock
這是每次運行pod install時創建的Podfile.lock文件的副本。如果你見過“沙盒文件和Podfile.lock文件不同步”的錯誤,這個錯誤就是因Manifest.lock文件和Podfile.lock文件不一樣引起。由於Pods所在的目錄並不總在版本控制之下,這樣可以保證開發者運行app之前都能更新他們的pods,否則app可能會crash,或者在一些不太明顯的地方編譯失敗
xcproj
如果您已經依照我們的建議在系統上安裝了xcproj,它會將您的Pods.xcodeproj文件轉換成就舊有ASCII格式的plist文件。為什么要這么做呢?因為Xcode所依賴和使用的plist在很久以前就已經不被其他軟件支持了。如果沒有xcproj,你的Pods.xcodeproj文件將會以XML格式的plist文件存儲,當你用Xcode打開它時,它會被改寫,造成大量的文件沖突。
運行結果
運行pod install的最終結果是許多文件被添加到你的工程和系統中。這個過程通常只需要幾秒鍾。當然沒有Cocoapods這些事也都可以完成。只不過所花的時間就不僅僅是幾秒而已了。
旁注:持續集成
CocoaPods和持續集成在一起非常融洽。雖然持續集成很大程度上取決於你的項目配置,但Cocoapods依然能很容易地對項目進行編譯。
Pods文件夾已加入版本控制的持續集成
如果包括Pods文件夾的一切東西都在版本控制之中,那么你不需要特別做什么就能夠持續集成。由於編譯時必須指定一個scheme,所以只需要保證使用了正確的scheme即可。
沒有Pods文件夾的持續集成
如果你的Pods文件夾沒有被納入版本控制之中,那么你需要一些額外的步驟來保證持續集成的順利進行。最起碼,Podfile文件要放入版本控制之中。另外強烈建議將生成的.xcworkspace文件和Podfile.lock文件納入版本控制,這樣不僅簡單方便,更能保證所使用的Pod是正確的版本。
一旦配置完畢,讓CocoaPods在CI上正確運行的關鍵是保證每次編譯之前都執行了pod install。在大多數系統中,譬如Jenkins或者Travis,你只用把“pod install”定義為一個編譯步驟即可(實際上,Travis會自動執行pod install)。隨着Xcode Bot的發布,我們還沒有找到能像書寫的這么流暢的解決方案,不過我們正朝着解決方案努力,一旦成功,我們將會立即分享。
結束語
CocoaPods簡化了OC的開發流程,我們的目標是讓第三方庫更容易被發現和添加。了解CocoaPods的原理能讓你做出更好的App。我們沿着CocoaPods的整個流程一步步執行,從載入specs文件和源代碼、創建.xcodeproj文件和所有組件到將所有文件寫入磁盤。所以接下來,我們運行 pod install –verbose,靜靜觀察CocoaPods的魔力如何顯現。
原文鏈接: Michele Titolo 翻譯: 伯樂在線 - programmer.du
譯文鏈接: http://blog.jobbole.com/53365/