1. 程式人生 > >Cocoa包管理器之CocoaPods詳解

Cocoa包管理器之CocoaPods詳解

CocoaPods在Cocoa開發日常工作中經常用到的包管理器,即依賴管理工具。有的專案也有用Carthage的,Carthage是一個比較新的依賴管理工具,是使用Swift語言開發的。Carthage在上家公司的一個專案中實踐過一些,用著也挺方便。本篇部落格就先系統的瞭解一下CocoaPods的使用方式和工作原理, 然後在下篇部落格中會系統的瞭解一下Carthage的使用方式和工作原理,這兩個依賴倉庫系統梳理完畢後,會做一個比較。

CocoaPods是個老生常談的話題。在之前的部落格中也有相關內容的涉及,但是不夠系統全面。本篇部落格會系統的梳理一下CocoaPods, 但是接下來幾篇部落格中會聊一些Carthage以及其原始碼解析的相關內容。

(注:部落格中的有些內容是自己根據具體的事例而總結出來的,有些地方如果理解偏差,還請大家進行斧正)

一、What is 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.

上面大概意思是CocoaPodsSwiftObjective-C語言中Cocoa專案中依賴的管理工具。其中涵蓋了4.5萬個庫,被300萬個App使用。CocoaPods可以幫助你優雅的擴從你的專案。

簡單點兒說CocoaPods就是Cocoa工程中被廣泛使用的包管理器。

二、Install CocoaPods

看完介紹,接下來簡單看一下CocoaPods的安裝。CocoaPods的編譯和執行需要Ruby環境的支援。在OS X上已經預設安裝了Ruby環境,官方推薦使用預設的Ruby環境。

可以通過下方的命令來安裝CocoaPods。在安裝時需新增上sudo, 使用系統許可權來進行安裝。下方的命令也可以用來更新CocoaPods

按照命令:sudo gem install cocoapods
解除安裝命令:gem uninstall cocoapods

因為我的本地之前已經安裝過CocoaPods, 下方是進行的覆蓋安裝,也相當於更新了。具體如下所示
  

三、Get Started

安裝完CocoaPods後,來看一下CocaPods的簡單使用。雖然在之前的部落格中不止一次的用到CocoaPods, 但是在本篇部落格安裝完CocoaPods後,接下來我們來簡單的感受一下CocoaPods的具體使用。

1、Create Podfile

CocoaPods管理的工程中通過名為Podfile的文字檔案來描述相關的依賴資訊。下方就是在我們已有的工程中建立了一個Podfile檔案,將下方的內容輸入到檔案中。在該檔案中通過pod來引入相關的倉庫,後方跟的是倉庫的版本號。下方的use_frameworks!則表明依賴的庫編譯生成.frameworkds的包,而不是.a的包。

platform :ios, '9.0'
use_frameworks!

target 'CocoaPodsTestProject' do
  pod 'AFNetworking', '~> 2.6'
end

下方就是建立Podfile檔案,然後將上述的內容輸入到該檔案中。
  

上面的platform指定的版本是倉庫相容的最小版本。target則指定的是作用於工程中的那個目標。pod則用來指定相關的倉庫及倉庫版本。下方是相關倉庫版本的幾種常見的指定方式:

  • pod 'xxxx' : 後方沒有指定版本,則表示使用倉庫的最新版本。
  • pod 'xxxx', '2.3' : 使用xxxx倉庫的2.3版本。
  • pod 'xxxx', '~>2.3': 則表示使用的版本範圍是 2.3 <= 版本 < 3.0。如果後方指定版本是~>2.3.1, 那麼則表示使用的版本範圍是 2.3.1 <= 版本 < 2.4.0
  • pod 'xxxx', '>2.3': 使用大於2.3的版本。
  • pod 'xxxx', '>=2.3': 使用2.3及以上的版本。
  • pod 'xxxx', '<2.3': 使用小於2.3的版本。
  • pod 'xxxx', '<=2.3': 使用小於等於2.3的版本。

除了上述的版本指定方式,我們還可以通過指定相關程式碼倉庫的路徑來指定相關的依賴,比如使用path來指定本地的相關倉庫,使用git來指定遠端的git倉庫。下方是常用的幾種方式:

  • pod 'xxx', :path => '原生代碼倉庫的路徑/xxx.podspec' #使用該方式可以指定本地存在的依賴路徑(podspec檔案稍後會結介紹到)。
  • pod 'xxx', :git => 'git倉庫地址' #可以通過git倉庫地址來載入相關依賴。
  • pod 'xxx', :git => '原生代碼倉庫的路徑', :tag => '2.2.2' :#後方可以跟:tag引數來指定相關的tag號。當然後邊還可以通過:branch => '分支號'來指定依賴於某個分支,通過:commit => 'commit號'來指定那個提交。

2、Pod Install

配置完Podfile檔案,接下來就是該在相關的工程中安裝相關的依賴了。下方使用了pod install來安裝相關的依賴,使用pod update來更新相關的依賴。在安裝依賴時會提示安裝了哪些依賴的庫。因為CocoaPods在安裝後會修改我們的Xcode工程,生成一個工作空間,這個工作空間由我們的Project工程和Pods工程組成,我們所依賴的倉庫就位於這個Pods工程中,所以安裝完畢後提示要通過xxxx.xcworkspace檔案來開啟整個工程。pod install完畢後,我們會發現整個工程中多了一些檔案,比如xxxx.xcworkspacePodsPodfile.lock等。我們就通xxxx.xcworkspace來開啟相關檔案,其他檔案稍後會介紹到。

  

下方就是我們通過open CocoaPodsTestProject.xcworkspace開啟的相關工程。下方的Pods中就包括相關依賴的倉庫。我們就可以在我們的工程中直接引入使用所依賴的倉庫了。上面也提到了,安裝後會生成一個工作空間workspace。該workspace就由我們原有的工程和新增的Pods工程組成。通過CocoaPods管理的依賴庫都會放在這個Pods工程中。具體如下所示:

  

3、鎖版檔案 podfile.lock

上面簡單的提了一下podfile.lock檔案。咋安裝之前我們建立了一個叫做 podfile 的依賴相關的描述檔案。在pod install後會生成一個叫做podfile.lock的檔案。下方截圖中是該檔案中的相關內容。其中記錄了目前依賴的一些倉庫以及一些版本,該檔案的目的就是鎖定依賴倉庫版本的。該 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檔案的作用。我們將podfile中的AFNetworking的版本號給刪掉,然後再次進行pod install。此刻並不會安裝最新的AF版本,因為在podfile.lock中已經記錄下了當前使用的AF版本了,所以再次進行 pod install 時仍然會載入 podfile.lock中記錄的版本。

  

當然你可以使用pod update命令來進行更新,使podfile.lock中記錄的版本進行更新。當然也可以在podfile檔案中指定相關依賴倉庫的版本,然後再執行pod install來更新相關的版本。具體如下所示 :

  

四、建立併發布自己的開源庫

 上面三個部分介紹瞭如何在自己的專案中安裝和使用CocoaPods,接下來這部分就來介紹一下如果將自己的開源的庫接入到CocoaPods中,可以讓其他人直接在Podfile中直接配置後,pod install就可以使用。下方是這一系列的操作。

1、建立自己的開源倉庫

下方以Github為例,首先我們在Github上建立了一個新的倉庫用來容納我們要開源的程式碼。如下所示:

  

在New Repository時, 選擇建立公共倉庫,然後勾選上建立README,最後別忘了並選擇開源協議。此處我們選擇的是MIT協議,下方會對Github上支援的開源協議進行介紹。

  

2、主流開源協議介紹

Github中支援了主流的幾種開源協議,如:Apache、GPL、MIT、BSD、Mozilla等下方羅列了Github上支援的開源協議,具體介紹如下:

  • Apache License 2.0 :Apache Licence是著名的非盈利開源組織Apache採用的協議。簡單的說,遵循該協議標誌著自己希望自己的專利能在開源免費使用的同時,保留自己在開源產品中的專利權益。同樣,該協議要求使用者必須保留你的版權資訊。
  • MIT License (麻省理工學院許可證) : 一個簡短、寬鬆、自由的協議。該協議允許人們使用你的程式碼,但必須要保留你的版權資訊。與此同時,並不會給你帶來任何責任和風險。
  • BSD(Berkly Software Distribution) : 也是一個比較寬泛自由的協議,該協議允許其他人修改程式碼,並進行二次釋出,並且可以用於商業活動。但是要保留原有程式碼的BSD協議,並且不能以原作者或者機構的名字來做市場推廣。(Unix)
  • 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程式碼。
    • 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協議的程式碼,但要承擔程式碼產生的侵權責任。

  

3、如何去選擇你的開源協議

下圖是從網上拿過來的,可以根據下方的具體情況來選擇相關的開源協議。

  

4、配置podspec檔案併發布自己的原始碼 

(1) 建立 podsepc檔案

言歸正傳,在Github上建立好相關的工程並選好相關的開源協議後,將工程Clone到本地,新增上自己要開源的程式碼,然後在該工程中建立podspec檔案。可以通過 pod spec create 命令來建立相關的podsepc檔案。

pod sepc create PodspecFileName 

下方是具體的操作:

  

然後對建立好的podspec檔案進行編輯,新增上開源庫的工程名稱、版本、描述、開源協議、作者、平臺、原始碼等等。具體每項的配置CocoaPods官網上有說明文件,可以去仔細翻閱。

  

(2)、建立tag號並push到遠端

配置好podsepc檔案後,接著建立一個tag號,這個tag好要與podspec中的version相對應。建立完tag號後,不要忘記push到遠端。tag號push到遠端後,我們可以通過 pod spec lint xxxx.podspec 來測試一下我們配置的podspec是否正確。具體操作如下所示。

  

(3)、測試和建立CocoaPods賬號

往CocoaPods上整合開源庫,需要相關的CocoaPods賬號。我們可以通過 pod trunk me來檢視賬號是否存在。如果不存在會提示你進行註冊並且進行相關認證。下方就使用了一個為註冊過的賬號進行 trunk。然後進行了相關賬號的註冊和啟用

  

 註冊完後,需要進入郵箱進行賬號的啟用。

  

 再次進行trunk me測試

  

(4)、釋出

Git倉庫配置已經賬號註冊完畢後,接下來就開始往CocoaPods上釋出自己的倉庫了。我們可以通過 pod trunk push xxxxx.podspce 將podspec檔案釋出到CocoaPods的Spec倉庫中。完成這一操作,就完成的我們倉庫的釋出了。

  

(5)、倉庫引用

釋出完畢後我們可以通過 pod search 來進行搜尋我們釋出的庫。如下所示,可以正常搜到。釋出完畢後我們就可以正常的在Podfile中進行配置、然後 pod install進行安裝引用了,具體引用步驟和其他三方庫一樣,在此就不做過多贅述了。

  

五、CocoaPods的Specs倉庫即原始碼載入路徑

接下來我們來看一下CocoaPods的Specs倉庫,然後在Specs倉庫的基礎上在看一下CocoaPods是如何通過我們工程中所提供的Profile檔案來載入三方依賴倉庫的。

1、Specs倉庫

上面在釋出我們開原始碼時頁提到過,是將我們建立和配置的xxxx.podspec檔案釋出到 CocoaPods的Specs倉庫()。Specs倉庫中就存放著各個開源庫的各個版本的podspec檔案。

下方就是Github上CocoaPods的Specs倉庫。根據該倉庫的README中的資訊,我們可以看出該倉庫中儲存的是所有可以用pod 匯入的公有倉庫的release版本的podspec檔案。這些公開的倉庫必須遵循MIT協議的。具體如下所示:

  

下方就是我們從CocoaPods中的Specs倉庫裡邊找到的上面我們釋出的測試工程。在我們工程的資料夾下對應的是一個個版本(git倉庫的tag號),每個tag號下方對應的就是該版本的podspec檔案。我們在釋出我們的工程到CocoaPods的時,本質上是根據我們的工程名稱建立相關的資料夾,然後根據我們的tag號建立子資料夾,然後在子資料夾中上傳當前版本所對應的podspec檔案。

  

2、三方依賴的載入路徑

看完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真正的工作應該比下方要複雜的多,

  

六、建立私有的Specs倉庫

上面看完 CocoaPods 倉庫的 Specs 檔案後,接下來我們來看一下如何建立私有的 Specs 倉庫。當我們的工程比較大時,尤其是使用模組化開發是,我們的工程會依賴好多其他的倉庫。建立私有的Specs倉庫來管理私有的依賴倉庫是很有必要的。接下來就介紹一下如何建立私有的Sepcs倉庫,然後把我們私有的依賴庫釋出到我們自己的Specs倉庫中。

下方以Github為例,會在Github上建立相關的Specs

1、建立私有Specs Repo

首先我們需要做的是在Github上建立一個名為Specs的倉庫(該倉庫的名字可以根據具體情況命名)。然後在本地關聯該Specs倉庫到Pod的倉庫中。

pod repo add SpecsName SpecsGitAddr

新增完畢後我們可使用 pod repo 命令來檢視該倉庫是否正常新增到CocoaPods中。

  

我看可以用下方命令來看一下該Specs倉庫是否可用:

pod repo lint xxxxSpecsName

  

2、將私有依賴庫工布到自己的Specs倉庫中

經過第一步就算建立並關聯好了我們私有的Specs倉庫了,接下來我們就該將私有的依賴倉庫釋出到我們自己的Specs倉庫中了。這一發布的過程與之前我們將工程釋出到CocoaPods的Specs倉庫中是一致的。只不過是將CocoaPods的Specs名稱換成了上面我們配置的MyCustomSpec名稱。具體如下所示:

pod repo push XxxSpecs xxxx.podspec

  

釋出完以後,我們可以去本地還有遠端的Specs倉庫中去檢視釋出的相關倉庫的資訊,下方是我們本地的倉庫資訊。可以看出在push完畢後,在cocoapods的repos資料夾下的MyCustomSpec檔案中多了一個MyCocoaPodsTestProject 資料夾,該資料夾下存放的就是該依賴庫中的版本資訊和各個版本的 podspec 檔案。

  

我們也可以從github來檢視釋出的依賴庫的相關資訊,如下所示。該結構與CocoaPods的Specs倉庫時差不多的。

  

3、引入私有倉庫

依賴倉庫 push 完畢後,接下來就該正常使用相關的依賴倉庫了。不過使用時在Podfile中要指定相關Podspec的地址,配置完畢後就可以pod install直接使用了。

  

今天部落格就先到這兒吧,下篇部落格會介紹另一個Cocoa包管理器Carthage。