CocoaPods在Cocoa開發日常工作中經常用到的包管理器,即依賴管理工具。有的項目也有用Carthage的,Carthage是一個比較新的依賴管理工具,是使用Swift語言開發的。Carthage在上家公司的一個項目中實踐過一些,用着也挺友善。本篇部落格就先系統的了解一下CocoaPods的使用方式和工作原理, 然後在下篇部落格中會系統的了解一下Carthage的使用方式和工作原理,這兩個依賴倉庫系統梳理完畢後,會做一個比較。
CocoaPods是個老生常談的話題。在之前的部落格中也有相關内容的涉及,但是不夠系統全面。本篇部落格會系統的梳理一下CocoaPods, 但是接下來幾篇部落格中會聊一些Carthage以及其源碼解析的相關内容。
(注:部落格中的有些内容是自己根據具體的事例而總結出來的,有些地方如果了解偏差,還請大家進行斧正)
首先來看一下什麼是CocoaPods, 下方是CocoaPods官網上對CocoaPods的解釋。
CocoaPods is a dependency manager for Swift and Objective-C Cocoa projects. It has over 45 thousand libraries and is used in over 3 million apps. CocoaPods can help you scale your projects elegantly.
上面大概意思是<code>CocoaPods</code>是<code>Swift</code>和<code>Objective-C</code>語言中<code>Cocoa</code>項目中依賴的管理工具。其中涵蓋了4.5萬個庫,被300萬個App使用。<code>CocoaPods</code>可以幫助你優雅的擴從你的項目。
簡單點兒說<code>CocoaPods</code>就是Cocoa工程中被廣泛使用的包管理器。
看完介紹,接下來簡單看一下CocoaPods的安裝。<code>CocoaPods</code>的編譯和運作需要Ruby環境的支援。在OS X上已經預設安裝了Ruby環境,官方推薦使用預設的<code>Ruby</code>環境。
可以通過下方的指令來安裝<code>CocoaPods</code>。在安裝時需添加上<code>sudo</code>, 使用系統權限來進行安裝。下方的指令也可以用來更新<code>CocoaPods</code>
按照指令:sudo gem install cocoapods 解除安裝指令:gem uninstall cocoapods
因為我的本地之前已經安裝過<code>CocoaPods</code>, 下方是進行的覆寫安裝,也相當于更新了。具體如下所示

安裝完CocoaPods後,來看一下CocaPods的簡單使用。雖然在之前的部落格中不止一次的用到<code>CocoaPods</code>, 但是在本篇部落格安裝完<code>CocoaPods</code>後,接下來我們來簡單的感受一下<code>CocoaPods</code>的具體使用。
在<code>CocoaPods</code>管理的工程中通過名為<code>Podfile</code>的文本檔案來描述相關的依賴資訊。下方就是在我們已有的工程中建立了一個<code>Podfile</code>檔案,将下方的内容輸入到檔案中。在該檔案中通過pod來引入相關的倉庫,後方跟的是倉庫的版本号。下方的<code>use_frameworks!</code>則表明依賴的庫編譯生成<code>.frameworkds</code>的包,而不是<code>.a</code>的包。
下方就是建立<code>Podfile</code>檔案,然後将上述的内容輸入到該檔案中。
上面的<code>platform</code>指定的版本是倉庫相容的最小版本。<code>target</code>則指定的是作用于工程中的那個目标。<code>pod</code>則用來指定相關的倉庫及倉庫版本。下方是相關倉庫版本的幾種常見的指定方式:
<code>pod 'xxxx'</code> : 後方沒有指定版本,則表示使用倉庫的最新版本。
<code>pod 'xxxx', '2.3'</code> : 使用xxxx倉庫的<code>2.3</code>版本。
<code>pod 'xxxx', '~>2.3'</code>: 則表示使用的版本範圍是 <code>2.3 <= 版本 < 3.0</code>。如果後方指定版本是<code>~>2.3.1</code>, 那麼則表示使用的版本範圍是 <code>2.3.1 <= 版本 < 2.4.0</code>。
<code>pod 'xxxx', '>2.3'</code>: 使用大于2.3的版本。
<code>pod 'xxxx', '>=2.3'</code>: 使用2.3及以上的版本。
<code>pod 'xxxx', '<2.3'</code>: 使用小于2.3的版本。
<code>pod 'xxxx', '<=2.3'</code>: 使用小于等于2.3的版本。
除了上述的版本指定方式,我們還可以通過指定相關代碼倉庫的路徑來指定相關的依賴,比如使用<code>path</code>來指定本地的相關倉庫,使用<code>git</code>來指定遠端的git倉庫。下方是常用的幾種方式:
<code>pod 'xxx', :path => '本地代碼倉庫的路徑/xxx.podspec'</code> #使用該方式可以指定本地存在的依賴路徑(podspec檔案稍後會結介紹到)。
<code>pod 'xxx', :git => 'git倉庫位址'</code> #可以通過git倉庫位址來加載相關依賴。
<code>pod 'xxx', :git => '本地代碼倉庫的路徑', :tag => '2.2.2'</code> :#後方可以跟<code>:tag</code>參數來指定相關的tag号。當然後邊還可以通過<code>:branch => '分支号'</code>來指定依賴于某個分支,通過<code>:commit => 'commit号'</code>來指定那個送出。
配置完<code>Podfile</code>檔案,接下來就是該在相關的工程中安裝相關的依賴了。下方使用了<code>pod install</code>來安裝相關的依賴,使用<code>pod update</code>來更新相關的依賴。在安裝依賴時會提示安裝了哪些依賴的庫。因為CocoaPods在安裝後會修改我們的Xcode工程,生成一個工作空間,這個工作空間由我們的Project工程和Pods工程組成,我們所依賴的倉庫就位于這個Pods工程中,是以安裝完畢後提示要通過<code>xxxx.xcworkspace</code>檔案來打開整個工程。<code>pod install</code>完畢後,我們會發現整個工程中多了一些檔案,比如<code>xxxx.xcworkspace</code>、<code>Pods</code>、<code>Podfile.lock</code>等。我們就通<code>xxxx.xcworkspace</code>來打開相關檔案,其他檔案稍後會介紹到。
下方就是我們通過<code>open CocoaPodsTestProject.xcworkspace</code>打開的相關工程。下方的Pods中就包括相關依賴的倉庫。我們就可以在我們的工程中直接引入使用所依賴的倉庫了。上面也提到了,安裝後會生成一個工作空間workspace。該workspace就由我們原有的工程和新增的Pods工程組成。通過CocoaPods管理的依賴庫都會放在這個Pods工程中。具體如下所示:
上面簡單的提了一下<code>podfile.lock</code>檔案。咋安裝之前我們建立了一個叫做 podfile 的依賴相關的描述檔案。在<code>pod install</code>後會生成一個叫做<code>podfile.lock</code>的檔案。下方截圖中是該檔案中的相關内容。其中記錄了目前依賴的一些倉庫以及一些版本,該檔案的目的就是鎖定依賴倉庫版本的。該 podfile.lock 本質上是用來鎖版本的,為了避免版本不一緻的情況發生。
我們來看一下如果沒有Podfile.lock檔案,會發生什麼情況。當在 podfile 中添加了相關依賴倉庫,但是沒有添加相關的依賴倉庫的版本,那麼在每次 pod insall 時都會安裝該倉庫最新的版本。當一個工程有多個人開發時,A同學 在 B同學 之前進行的pod install, 而在A同學安裝後一些倉庫進行了更新,那麼在 B同學 安裝倉庫時就會尋找這個最新的版本。那麼這種情況下就會出現同一個工程中所依賴的倉庫版本不一緻的問題。為了解決這個版本不一緻的問題,于是乎就引入了Podfile.lock這個所版本用的檔案。當然在架構中的包管理器中也是存在類似的lock檔案的,比如 node.js 中的npm包管理器。
引入 podfile.lock 檔案後,上面的版本不一緻的問題就很好的解決了。在首次 pod install 後,會生成一個 podfile.lock 檔案,該檔案中會記錄此次 install 所安裝的版本。當再次進行 pod install時,對那些沒有指定版本的依賴倉庫會使用podfile.lock 檔案中記錄的版本。如果在 podfile 中指定了相關版本,那麼就直接引用 podfile 中指定的版本然後在更新 podfile.lock中記錄的版本即可。
接下來我們通過具體示例來看一下該podfile.lock檔案的作用。我們将<code>podfile</code>中的AFNetworking的版本号給删掉,然後再次進行pod install。此刻并不會安裝最新的AF版本,因為在<code>podfile.lock</code>中已經記錄下了目前使用的<code>AF</code>版本了,是以再次進行 pod install 時仍然會加載 podfile.lock中記錄的版本。
當然你可以使用<code>pod update</code>指令來進行更新,使<code>podfile.lock</code>中記錄的版本進行更新。當然也可以在<code>podfile</code>檔案中指定相關依賴倉庫的版本,然後再執行<code>pod install</code>來更新相關的版本。具體如下所示 :
上面三個部分介紹了如何在自己的項目中安裝和使用CocoaPods,接下來這部分就來介紹一下如果将自己的開源的庫接入到CocoaPods中,可以讓其他人直接在Podfile中直接配置後,pod install就可以使用。下方是這一系列的操作。
下方以Github為例,首先我們在Github上建立了一個新的倉庫用來容納我們要開源的代碼。如下所示:
在New Repository時, 選擇建立公共倉庫,然後勾選上建立README,最後别忘了并選擇開源協定。此處我們選擇的是MIT協定,下方會對Github上支援的開源協定進行介紹。
Github中支援了主流的幾種開源協定,如:Apache、GPL、MIT、BSD、Mozilla等下方羅列了Github上支援的開源協定,具體介紹如下:
Apache License 2.0 :Apache Licence是著名的非盈利開源組織Apache采用的協定。簡單的說,遵循該協定标志着自己希望自己的專利能在開源免費使用的同時,保留自己在開源産品中的專利權益。同樣,該協定要求使用者必須保留你的版權資訊。
MIT License (麻省理工學院許可證) : 一個簡短、寬松、自由的協定。該協定允許人們使用你的代碼,但必須要保留你的版權資訊。與此同時,并不會給你帶來任何責任和風險。
BSD(Berkly Software Distribution) : 也是一個比較寬泛自由的協定,該協定允許其他人修改代碼,并進行二次釋出,并且可以用于商業活動。但是要保留原有代碼的BSD協定,并且不能以原作者或者機構的名字來做市場推廣。(Unix)
BSD 2-Clause "Simplified" License : 簡化版本的BSD協定, 修改版本必須保持其原始版權聲明。
BSD 3-Clause "New" or "Revised" License : 新的或者經過重新修訂的BSD協定, 修改版本必須保持其原始版權聲明。未經許可不得使用原作者或公司的名字做宣傳。
GPL (GNU General Public License - GNU通用公共許可協定) : 如果你希望别人在分享的自己的作品之後,也必須遵循相同的協定,也必須是開源和免費,那麼就選擇GPL協定。也就是說隻要你用了任何該協定的庫、甚至是一段代碼,那麼你的整個程式,不管以何種方式連結,都必須全部使用GPL協定、并遵循該協定開源。商業軟體公司一般禁用GPL代碼,但可以使用GPL的可執行檔案和應用程式。
GNU General Public License v2.0
GUN General Public License v3.0
GNU Affero General Public License v2.0 : Affero通用公共許可,基于GPL的擴充。即Affero GPL,是GPL的更嚴格版本。隻要你用了任何該協定的庫、甚至是一段代碼,那麼運作時和它相關的所有軟體、包括通過網絡聯系的所有軟體,必須全部遵循該協定開源。據律師說,它的要求範圍連硬體都包括。是以,一般公司通常禁用任何AGPL代碼。
LGPL : GNU Lesser General Public License - GNU寬松的通用公共許可協定,就是GPL針對動态連結庫放松要求了的版本,即允許非LGPL的代碼動态連結到LGPL的子產品。注意:不可以靜态連結,否則你的代碼也必須用LGPL協定開源。Mozilla Public License 2.0 : MPL - 修改版本必須保持其原始版權聲明。如果釋出了編譯後的可執行檔案,那麼必須讓對方可以取得MPL協定下程式的源碼。
GNU Lesser General Public License v2.1
GNU Lesser General Public License v3.0
The Unlicense : 在許多國家,預設版權歸作者自動擁有,是以Unlicense協定提供了一種通用的模闆,此協定表明你放棄版權,将勞動成果無私貢獻出來。你将喪失對作品的全部權利,包括在MIT/X11中定義的無擔保權利。
Eclipse Public License 2.0 : EPL由Eclipse基金會應用于名下的內建開發環境Eclipse上, 商業軟體可以使用,也可以修改EPL協定的代碼,但要承擔代碼産生的侵權責任。
下圖是從網上拿過來的,可以根據下方的具體情況來選擇相關的開源協定。
言歸正傳,在Github上建立好相關的工程并選好相關的開源協定後,将工程Clone到本地,添加上自己要開源的代碼,然後在該工程中建立podspec檔案。可以通過 pod spec create 指令來建立相關的podsepc檔案。
pod sepc create PodspecFileName
下方是具體的操作:
然後對建立好的podspec檔案進行編輯,添加上開源庫的工程名稱、版本、描述、開源協定、作者、平台、源代碼等等。具體每項的配置CocoaPods官網上有說明文檔,可以去仔細翻閱。
配置好podsepc檔案後,接着建立一個tag号,這個tag好要與podspec中的version相對應。建立完tag号後,不要忘記push到遠端。tag号push到遠端後,我們可以通過 pod spec lint xxxx.podspec 來測試一下我們配置的podspec是否正确。具體操作如下所示。
往CocoaPods上內建開源庫,需要相關的CocoaPods賬号。我們可以通過 pod trunk me來檢視賬号是否存在。如果不存在會提示你進行注冊并且進行相關認證。下方就使用了一個為注冊過的賬号進行 trunk。然後進行了相關賬号的注冊和激活
注冊完後,需要進入郵箱進行賬号的激活。
再次進行trunk me測試
Git倉庫配置已經賬号注冊完畢後,接下來就開始往CocoaPods上釋出自己的倉庫了。我們可以通過 pod trunk push xxxxx.podspce 将podspec檔案釋出到CocoaPods的Spec倉庫中。完成這一操作,就完成的我們倉庫的釋出了。
釋出完畢後我們可以通過 pod search 來進行搜尋我們釋出的庫。如下所示,可以正常搜到。釋出完畢後我們就可以正常的在Podfile中進行配置、然後 pod install進行安裝引用了,具體引用步驟和其他三方庫一樣,在此就不做過多贅述了。
接下來我們來看一下CocoaPods的Specs倉庫,然後在Specs倉庫的基礎上在看一下CocoaPods是如何通過我們工程中所提供的Profile檔案來加載三方依賴倉庫的。
上面在釋出我們開源代碼時頁提到過,是将我們建立和配置的xxxx.podspec檔案釋出到 CocoaPods的Specs倉庫(https://github.com/CocoaPods/Specs.git)。Specs倉庫中就存放着各個開源庫的各個版本的podspec檔案。
下方就是Github上CocoaPods的Specs倉庫。根據該倉庫的README中的資訊,我們可以看出該倉庫中存儲的是所有可以用pod 導入的公有倉庫的release版本的podspec檔案。這些公開的倉庫必須遵循MIT協定的。具體如下所示:
下方就是我們從CocoaPods中的Specs倉庫裡邊找到的上面我們釋出的測試工程。在我們工程的檔案夾下對應的是一個個版本(git倉庫的tag号),每個tag号下方對應的就是該版本的podspec檔案。我們在釋出我們的工程到CocoaPods的時,本質上是根據我們的工程名稱建立相關的檔案夾,然後根據我們的tag号建立子檔案夾,然後在子檔案夾中上傳目前版本所對應的podspec檔案。
看完Specs倉庫裡邊的内容後,接下來我們來看一下我們CocoaPods是如何通過我們工程中的Podfile檔案來加載相關的三方依賴庫的。
首先我們來看一下Podfile中的基本結構。在Podfile檔案中,其中的 source 參數就是用來指定依賴倉庫所對應的Specs倉庫的, source的預設位址就是CocoaPods的 Specs 倉庫。如果我們有自己的私有 Specs 倉庫,也可以指定我們自己的Specs倉庫位址。
在Podfile中可以指定多個 Specs 倉庫的位址,稍後我們會建立我們自己的Specs倉庫,然後在該Specs倉庫中上次釋出我們自己使用的依賴庫。
下方是CocoaPods中加載依賴倉庫代碼的路徑,根據自己的了解,尋找源碼路徑大體上分為下方幾個步驟:
通過Podfile這個 source 指定的Specs倉庫的位址,我們就可以找到相關的Specs倉庫。
找到Specs倉庫後,再根據 Podfile 中所提供的倉庫依賴配置(比如 pod 'AFNetWorkiing', ~>'2.6.3'),找到指定的依賴倉庫和相關的版本。
然後找到該版本所對應的 xxx.podspec 檔案。
然後再根據 xxx.podsepce 檔案中的相關配置資訊找到該倉庫所對應的源碼的git位址。
最後根據源碼的git位址加載三方倉庫到Pods工程中統一管理。
下方是根據上方的步驟所畫的簡圖。CocoaPods真正的工作應該比下方要複雜的多,
上面看完 CocoaPods 倉庫的 Specs 檔案後,接下來我們來看一下如何建立私有的 Specs 倉庫。當我們的工程比較大時,尤其是使用子產品化開發是,我們的工程會依賴好多其他的倉庫。建立私有的Specs倉庫來管理私有的依賴倉庫是很有必要的。接下來就介紹一下如何建立私有的Sepcs倉庫,然後把我們私有的依賴庫釋出到我們自己的Specs倉庫中。
下方以Github為例,會在Github上建立相關的Specs
首先我們需要做的是在Github上建立一個名為Specs的倉庫(該倉庫的名字可以根據具體情況命名)。然後在本地關聯該Specs倉庫到Pod的倉庫中。
pod repo add SpecsName SpecsGitAddr
添加完畢後我們可使用 pod repo 指令來檢視該倉庫是否正常添加到CocoaPods中。
我看可以用下方指令來看一下該Specs倉庫是否可用:
pod repo lint xxxxSpecsName
經過第一步就算建立并關聯好了我們私有的Specs倉庫了,接下來我們就該将私有的依賴倉庫釋出到我們自己的Specs倉庫中了。這一釋出的過程與之前我們将工程釋出到CocoaPods的Specs倉庫中是一緻的。隻不過是将CocoaPods的Specs名稱換成了上面我們配置的MyCustomSpec名稱。具體如下所示:
pod repo push XxxSpecs xxxx.podspec
釋出完以後,我們可以去本地還有遠端的Specs倉庫中去檢視釋出的相關倉庫的資訊,下方是我們本地的倉庫資訊。可以看出在push完畢後,在cocoapods的repos檔案夾下的MyCustomSpec檔案中多了一個MyCocoaPodsTestProject 檔案夾,該檔案夾下存放的就是該依賴庫中的版本資訊和各個版本的 podspec 檔案。
我們也可以從github來檢視釋出的依賴庫的相關資訊,如下所示。該結構與CocoaPods的Specs倉庫時差不多的。
依賴倉庫 push 完畢後,接下來就該正常使用相關的依賴倉庫了。不過使用時在Podfile中要指定相關Podspec的位址,配置完畢後就可以pod install直接使用了。
今天部落格就先到這兒吧,下篇部落格會介紹另一個Cocoa包管理器Carthage。
作者:青玉伏案
出處:http://www.cnblogs.com/ludashi/
本文版權歸作者和共部落格園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接配接,否則保留追究法律責任的權利。
如果文中有什麼錯誤,歡迎指出。以免更多的人被誤導。
收履歷:某網際網路公司,招聘iOS/Android靠譜工程師,入職後,可内部聯系樓主,有小禮品贈送,有意者可郵箱投遞履歷:[email protected]