Cocoapods
是很是好用的一個iOS
依賴管理工具,使用它能夠方便的管理和更新項目中所使用到的第三方庫,以及將本身的項目中的公共組件交由它去管理。Cocoapods
的介紹及優勢本文就不在贅述,我開始使用Cocoapods
仍是在兩年前,那個時候它剛剛出現,網上的資料還很是的少,就連他們本身的HomePage
都十分的簡單,我就着手嘗試着使用了一下,用它管理起第三方庫確實是十分的方便順手。後來它有了更強大的功能就是本身建立podspec
,更能夠設置私有的庫。html
春節回來上班,一天的工做結束以後,須要充實下本身,正好項目中有一些公共組件須要從龐大的項目體系中剝離出來,並且年前項目終於從SVN
遷移到了Git
,真是喜大普奔,大快人心!這樣項目使用Cocoapods
就有了條件,正好學習一下建立私有的podspec
並在項目中部署使用,以及pods
的subspec
的建立及使用。ios
總體先說明一下建立一個私有的podspec
包括以下那麼幾個步驟:git
Spec Repo
。Pod
的所須要的項目工程文件,而且有可訪問的項目版本控制地址。Pod
所對應的podspec
文件。podspec
文件是否可用。Spec Repo
中提交podspec
。Podfile
中增長剛剛製做的好的Pod
並使用。podspec
。在這一系列的步驟中須要建立兩個Git倉庫
,分別是第一步和第二步(第二步不必定非要是Git倉庫
,只要是能夠獲取到相關代碼文件就能夠,也能夠是SVN
的,也能夠說zip包
,區別就是在podspec
中的source
項填寫的內容不一樣),而且第一步只是在初次建立私有podspec
時才須要,以後在建立其餘的只須要從第二步開始就能夠。本文只介紹在Git
環境下的操做,其餘環境其餘方式暫不說明。github
Spec Repo
先來講第一步,什麼是Spec Repo
?他是全部的Pods
的一個索引,就是一個容器,全部公開的Pods
都在這個裏面,他實際是一個Git倉庫
remote端
在GitHub
上,可是當你使用了Cocoapods
後他會被clone
到本地的~/.cocoapods/repos
目錄下,能夠進入到這個目錄看到master
文件夾就是這個官方的Spec Repo
了。這個master
目錄的結構是這個樣子的xcode
1
2 3 4 5 |
. ├── Specs └── [SPEC_NAME] └── [VERSION] └── [SPEC_NAME].podspec |
所以咱們須要建立一個相似於master
的私有Spec Repo
,這裏咱們能夠fork
官方的Repo
,也能夠本身建立,我的建議不fork
,由於你只是想添加本身的Pods
,沒有必要把現有的公開Pods
都copy
一份。因此建立一個 Git倉庫
,這個倉庫你能夠建立私有的也能夠建立公開的,不過既然私有的Spec Repo
,仍是建立私有的倉庫吧,須要注意的就是若是項目中有其餘同事共同開發的話,你還要給他這個Git倉庫
的權限。由於GitHub
的私有倉庫是收費的,我還不是GitHub
的付費用戶,因此我使用了其餘Git
服務,我使用的是CODING
,固然還有其餘的可供選擇開源中國
、Bitbucket
以及CSDN
ruby
建立完成以後在Terminal
中執行以下命令bash
1
2 |
# pod repo add [Private Repo Name] [GitHub HTTPS clone URL] $ pod repo add WTSpecs https://coding.net/wtlucky/WTSpecs.git |
此時若是成功的話進入到~/.cocoapods/repos
目錄下就能夠看到WTSpecs
這個目錄了。至此第一步建立私有Spec Repo
完成。markdown
PS:若是有其餘合做人員共同使用這個私有Spec Repo
的話在他有對應Git倉庫
的權限的前提下執行相同的命令添加這個Spec Repo
便可。網絡
Pod
項目工程文件這個第二步沒有什麼好介紹的,若是是有現有的組件項目,而且在Git
的版本管理下,那麼這一步就算完成了,能夠直接進行下一步了。框架
若是你的組件還在你冗餘龐大的項目中,須要拆分出來或者須要本身從零開始建立一個組件庫,那麼我建議你使用Cocoapods
提供的一個工具將第二步與第三步結合起來作。
如今來講一下這個工具,相關的文檔介紹是Using Pod Lib Create 就拿我建立的podTestLibrary
爲例子具體講一下這裏是如何操做的,先cd
到要建立項目的目錄而後執行
1
|
$ pod lib create podTestLibrary |
以後他會問你四個問題,1.是否須要一個例子工程;2.選擇一個測試框架;3.是否基於View測試;4.類的前綴;4個問題的具體介紹能夠去看官方文檔,我這裏選擇的是1.yes;2.Specta/Expecta;3.yes;4.PTL。 問完這4個問題他會自動執行pod install
命令建立項目並生成依賴。
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
$ tree PodTestLibrary -L 2 PodTestLibrary ├── Example #demo APP │ ├── PodTestLibrary │ ├── PodTestLibrary.xcodeproj │ ├── PodTestLibrary.xcworkspace │ ├── Podfile #demo APP 的依賴描述文件 │ ├── Podfile.lock │ ├── Pods #demo APP 的依賴文件 │ └── Tests ├── LICENSE #開源協議 默認MIT ├── Pod #組件的目錄 │ ├── Assets #資源文件 │ └── Classes #類文件 ├── PodTestLibrary.podspec #第三步要建立的podspec文件 └── README.md #markdown格式的README 9 directories, 5 files |
以上是項目生成的目錄結構及相關介紹。
接下來就是向Pod
文件夾中添加庫文件和資源,並配置podspec
文件,我把一個網絡模塊的共有組件放入Pod/Classes
中,而後進入Example
文件夾執行pod update
命令,再打開項目工程能夠看到,剛剛添加的組件已經在Pods
子工程下Development Pods/PodTestLibrary
中了,而後編輯demo工程,測試組件,我並無使用提供的測試框架進行測試,這裏就先不介紹了。
注:這裏須要注意的是每當你向Pod
中添加了新的文件或者之後更新了podspec
的版本都須要從新執行一遍pod update
命令。
測試無誤後須要將該項目添加並推送到遠端倉庫,並編輯podspec
文件。
經過Cocoapods
建立出來的目錄自己就在本地的Git
管理下,咱們須要作的就是給它添加遠端倉庫,一樣去GitHub
或其餘的Git
服務提供商那裏建立一個私有的倉庫,拿到SSH
地址,而後cd
到PodTestLibrary
目錄
1
2 3 4 |
$ git add . $ git commit -s -m "Initial Commit of Library" $ git remote add origin git@coding.net:wtlucky/podTestLibrary.git #添加遠端倉庫 $ git push origin master #提交到遠端倉庫 |
由於podspec
文件中獲取Git
版本控制的項目還須要tag
號,因此咱們要打上一個tag
,
1
2 |
$ git tag -m "first release" 0.1.0 $ git push --tags #推送tag到遠端倉庫 |
作完這些就能夠開始編輯podspec
文件了,它是一個Ruby
的文件,把編輯器的格式改爲Ruby
就能看到語法高亮,下面我貼上個人podspec
文件,並在後面以註釋的形式說明每一個字段的含義,沒有涉及到的字段能夠去官方文檔查閱
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 |
Pod::Spec.new do |s| s.name = "PodTestLibrary" #名稱 s.version = "0.1.0" #版本號 s.summary = "Just Testing." #簡短介紹,下面是詳細介紹 s.description = <<-DESC Testing Private Podspec. * Markdown format. * Don't worry about the indent, we strip it! DESC s.homepage = "https://coding.net/u/wtlucky/p/podTestLibrary" #主頁,這裏要填寫能夠訪問到的地址,否則驗證不經過 # s.screenshots = "www.example.com/screenshots_1", "www.example.com/screenshots_2" #截圖 s.license = 'MIT' #開源協議 s.author = { "wtlucky" => "wtlucky@foxmail.com" } #做者信息 s.source = { :git => "https://coding.net/wtlucky/podTestLibrary.git", :tag => "0.1.0" } #項目地址,這裏不支持ssh的地址,驗證不經過,只支持HTTP和HTTPS,最好使用HTTPS # s.social_media_url = 'https://twitter.com/<TWITTER_USERNAME>' #多媒體介紹地址 s.platform = :ios, '7.0' #支持的平臺及版本 s.requires_arc = true #是否使用ARC,若是指定具體文件,則具體的問題使用ARC s.source_files = 'Pod/Classes/**/*' #代碼源文件地址,**/*表示Classes目錄及其子目錄下全部文件,若是有多個目錄下則用逗號分開,若是須要在項目中分組顯示,這裏也要作相應的設置 s.resource_bundles = { 'PodTestLibrary' => ['Pod/Assets/*.png'] } #資源文件地址 s.public_header_files = 'Pod/Classes/**/*.h' #公開頭文件地址 s.frameworks = 'UIKit' #所需的framework,多個用逗號隔開 s.dependency 'AFNetworking', '~> 2.3' #依賴關係,該項目所依賴的其餘庫,若是有多個須要填寫多個s.dependency end |
編輯完podspec
文件後,須要驗證一下這個文件是否可用,若是有任何WARNING
或者ERROR
都是不能夠的,它就不能被添加到Spec Repo
中,不過xcode
的WARNING
是能夠存在的,驗證須要執行一下命令
1
|
$ pod lib lint |
當你看到
1
2 3 |
-> PodTestLibrary (0.1.0) PodTestLibrary passed validation. |
時,說明驗證經過了,不過這只是這個podspec
文件是合格的,不必定說明這個Pod
是能夠用的,咱們須要在本地作一下驗證,這就是第四步的內容了,第四步在具體說明。
podspec
文件若是從第二步過來,已經有了現成的項目,那麼就須要給這個項目建立一個podspec
文件,建立它須要執行Cocoapods
的另一個命令,官方文檔在這裏
1
|
$ pod spec create PodTestLibrary git@coding.net:wtlucky/podTestLibrary.git |
執行完以後,就建立了一個podspec
文件,他其中會包含不少內容,能夠按照我以前介紹的進行編輯,沒用的刪掉。編輯完成以後使用驗證命令驗證一下
1
|
$ pod lib lint |
驗證無誤就能夠進入下一步了。
podspec
文件咱們能夠建立一個新的項目,在這個項目的Podfile
文件中直接指定剛纔建立編輯好的podspec
文件,看是否可用。 在Podfile
中咱們能夠這樣編輯,有兩種方式
1
2 3 4 |
platform :ios, '7.0' pod 'PodTestLibrary', :path => '~/code/Cocoapods/podTest/PodTestLibrary' # 指定路徑 pod 'PodTestLibrary', :podspec => '~/code/Cocoapods/podTest/PodTestLibrary/PodTestLibrary.podspec' # 指定podspec文件 |
而後執行pod install
命令安裝依賴,打開項目工程,能夠看到庫文件都被加載到Pods
子項目中了,不過它們並無在Pods
目錄下,而是跟測試項目同樣存在於Development Pods/PodTestLibrary
中,這是由於咱們是在本地測試,而沒有把podspec
文件添加到Spec Repo
中的緣故。
在項目中編寫代碼,測試庫文件無誤後就能夠開始下一步了,提交podspec
到Spec Repo
中。
Spec Repo
提交podspec
向Spec Repo
提交podspec
須要完成兩點一個是podspec
必須經過驗證無誤,在一個就是刪掉無用的註釋(這個不是必須的,爲了規範仍是刪掉吧)。 向咱們的私有Spec Repo
提交podspec
只須要一個命令
1
|
$ pod repo push WTSpecs PodTestLibrary.podspec #前面是本地Repo名字 後面是podspec名字 |
完成以後這個組件庫就添加到咱們的私有Spec Repo
中了,能夠進入到~/.cocoapods/repos/WTSpecs
目錄下查看
1
2 3 4 5 6 |
. ├── LICENSE ├── PodTestLibrary │ └── 0.1.0 │ └── PodTestLibrary.podspec └── README.md |
再去看咱們的Spec Repo
遠端倉庫,也有了一次提交,這個podspec
也已經被Push
上去了。
至此,咱們的這個組件庫就已經制做添加完成了,使用pod search
命令就能夠查到咱們本身的庫了
1
2 3 4 5 6 7 8 |
$ pod search PodTestLibrary -> PodTestLibrary (0.1.0) Just Testing. pod 'PodTestLibrary', '~> 0.1.0' - Homepage: https://coding.net/u/wtlucky/p/podTestLibrary - Source: https://coding.net/wtlucky/podTestLibrary.git - Versions: 0.1.0 [WTSpecs repo] |
這裏說的是添加到私有的Repo
,若是要添加到Cocoapods
的官方庫了,可使用trunk
工具,具體能夠查看官方文檔
Pod
在完成這一系列步驟以後,咱們就能夠在正式項目中使用這個私有的Pod
了只須要在項目的Podfile
裏增長如下一行代碼便可
1
|
$ pod 'PodTestLibrary', '~> 0.1.0' |
而後執行pod update
,更新庫依賴,而後打卡項目能夠看到,咱們本身的庫文件已經出如今Pods
子項目中的Pods
子目錄下了,而再也不是Development Pods
。
podspec
最後再來講一下製做好的podspec
文件後續的更新維護工做,好比如何添加新的版本,如何刪除Pod
。
我已經制做好了PodTestLibrary
的0.1.0
版本,如今我對他進行升級工做,此次我添加了更多的模塊到PodTestLibrary
之中,包括工具類,底層Model
及UIKit
擴展等,這裏又嘗試了一下subspec
功能,給PodTestLibrary
建立了多個子分支。
具體作法是先將源文件添加到Pod/Classes
中,而後按照不一樣的模塊對文件目錄進行整理,由於我有四個模塊,因此在Pod/Classes
下有建立了四個子目錄,完成以後繼續編輯以前的PodTestLibrary.podspec
,此次增長了subspec
特性
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 |
Pod::Spec.new do |s| s.name = "PodTestLibrary" s.version = "1.0.0" s.summary = "Just Testing." s.description = <<-DESC Testing Private Podspec. * Markdown format. * Don't worry about the indent, we strip it! DESC s.homepage = "https://coding.net/u/wtlucky/p/podTestLibrary" # s.screenshots = "www.example.com/screenshots_1", "www.example.com/screenshots_2" s.license = 'MIT' s.author = { "wtlucky" => "wtlucky@foxmail.com" } s.source = { :git => "https://coding.net/wtlucky/podTestLibrary.git", :tag => "1.0.0" } # s.social_media_url = 'https://twitter.com/<TWITTER_USERNAME>' s.platform = :ios, '7.0' s.requires_arc = true #s.source_files = 'Pod/Classes/**/*' #s.resource_bundles = { # 'PodTestLibrary' => ['Pod/Assets/*.png'] #} #s.public_header_files = 'Pod/Classes/**/*.h' s.subspec 'NetWorkEngine' do |networkEngine| networkEngine.source_files = 'Pod/Classes/NetworkEngine/**/*' networkEngine.public_header_files = 'Pod/Classes/NetworkEngine/**/*.h' networkEngine.dependency 'AFNetworking', '~> 2.3' end s.subspec 'DataModel' do |dataModel| dataModel.source_files = 'Pod/Classes/DataModel/**/*' dataModel.public_header_files = 'Pod/Classes/DataModel/**/*.h' end s.subspec 'CommonTools' do |commonTools| commonTools.source_files = 'Pod/Classes/CommonTools/**/*' commonTools.public_header_files = 'Pod/Classes/CommonTools/**/*.h' commonTools.dependency 'OpenUDID', '~> 1.0.0' end s.subspec 'UIKitAddition' do |ui| ui.source_files = 'Pod/Classes/UIKitAddition/**/*' ui.public_header_files = 'Pod/Classes/UIKitAddition/**/*.h' ui.resource = "Pod/Assets/MLSUIKitResource.bundle" ui.dependency 'PodTestLibrary/CommonTools' end s.frameworks = 'UIKit' #s.dependency 'AFNetworking', '~> 2.3' #s.dependency 'OpenUDID', '~> 1.0.0' end |
由於咱們建立了subspec
因此項目總體的依賴dependency
,源文件source_files
,頭文件public_header_files
,資源文件resource
等都移動到了各自的subspec
中,每一個subspec
之間也能夠有相互的依賴關係,好比UIKitAddition
就依賴於CommonTools
。
編輯完成以後,在測試項目裏pod update
一下,幾個子項目都被加進項目工程了,寫代碼驗證無誤以後,就能夠將這個工程push
到遠端倉庫,並打上新的tag
->1.0.0
。
最後再次使用pod lib lint
驗證編輯好的podsepc
文件,沒有自身的WARNING
或者ERROR
以後,就能夠再次提交到Spec Repo
中了,命令跟以前是同樣的
1
|
$ pod repo push WTSpecs PodTestLibrary.podspec |
以後再次到~/.cocoapods/repos/WTSpecs
目錄下查看
1
2 3 4 5 6 7 8 9 10 |
. ├── LICENSE ├── PodTestLibrary │ ├── 0.1.0 │ │ └── PodTestLibrary.podspec │ └── 1.0.0 │ └── PodTestLibrary.podspec └── README.md 3 directories, 4 files |
已經有兩個版本了,使用pod search
查找獲得的結果爲
1
2 3 4 5 6 7 8 9 10 11 12 13 |
$ pod search PodTestLibrary -> PodTestLibrary (1.0.0) Just Testing. pod 'PodTestLibrary', '~> 1.0.0' - Homepage: https://coding.net/u/wtlucky/p/podTestLibrary - Source: https://coding.net/wtlucky/podTestLibrary.git - Versions: 1.0.0, 0.1.0 [WTSpecs repo] - Sub specs: - PodTestLibrary/NetWorkEngine (1.0.0) - PodTestLibrary/DataModel (1.0.0) - PodTestLibrary/CommonTools (1.0.0) - PodTestLibrary/UIKitAddition (1.0.0) |
完成這些以後,在實際項目中咱們就能夠選擇使用整個組件庫或者是組件庫的某一個部分了,對應的Podfile
中添加的內容爲
1
2 3 4 5 6 7 8 |
source 'https://github.com/CocoaPods/Specs.git' # 官方庫 source 'https://git.coding.net/wtlucky/WTSpecs.git' # 私有庫 platform :ios, '7.0' pod 'PodTestLibrary/NetWorkEngine', '1.0.0' #使用某一個部分 pod 'PodTestLibrary/UIKitAddition', '1.0.0' pod 'PodTestLibrary', '1.0.0' #使用整個庫 |
最後介紹一下如何刪除一個私有Spec Repo
,只須要執行一條命令便可
1
|
$ pod repo remove WTSpecs |
這樣這個Spec Repo
就在本地刪除了,咱們還能夠經過
1
|
$ pod repo add WTSpecs git@coding.net:wtlucky/WTSpecs.git |
再把它給加回來。
若是咱們要刪除私有Spec Repo
下的某一個podspec
怎麼操做呢,此時無需藉助Cocoapods
,只須要cd
到~/.cocoapods/repos/WTSpecs
目錄下,刪掉庫目錄
1
|
wtlucky@wtluckydeMacBook-Pro:~/.cocoapods/repos/WTSpecs$ rm -Rf PodTestLibrary |
而後在將Git
的變更push
到遠端倉庫便可
1
2 3 |
wtlucky@wtluckydeMacBook-Pro:~/.cocoapods/repos/WTSpecs$ git add --all . wtlucky@wtluckydeMacBook-Pro:~/.cocoapods/repos/WTSpecs$ git ci -m "remove unuseful pods" wtlucky@wtluckydeMacBook-Pro:~/.cocoapods/repos/WTSpecs$ git push origin master |
Developing Private In-House Libraries with CocoaPods
http://blog.wtlucky.com/blog/2015/02/26/create-private-podspec/