[轉]iOS系列譯文:深入理解 CocoaPods


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/


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM