Cocoapods
是非常好用的一個iOS
依賴管理工具,使用它可以方便的管理和更新項目中所使用到的第三方庫,以及將自己的項目中的公共組件交由它去管理。
創建一個私有的podspec
包括如下那么幾個步驟:
- 創建并設置一個私有的
Spec Repo
。 - 創建
Pod
的所需要的項目工程文件,并且有可訪問的項目版本控制地址。 - 創建
Pod
所對應的podspec
文件。 - 本地測試配置好的
podspec
文件是否可用。 - 向私有的
Spec Repo
中提交podspec
。 - 在個人項目中的
Podfile
中增加剛剛制作的好的Pod
并使用。 - 更新維護
podspec
。
在這一系列的步驟中需要創建兩個Git
倉庫,分別是第一步和第二步(第二步不一定非要是Git
倉庫,只要是可以獲取到相關代碼文件就可以,也可以是SVN
的,也可以說zip
包,區別就是在podspec
中的source
項填寫的內容不同),并且第一步只是在初次創建私有podspec
時才需要,之后在創建其他的只需要從第二步開始就可以。本文只介紹在Git
環境下的操作,其他環境其他方式暫不說明。
創建私有Spec Repo
先來說第一步,什么是Spec Repo
?他是所有的Pods
的一個索引,就是一個容器,所有公開的Pods
都在這個里面,他實際是一個Gi
t倉庫remote
端 在GitHub
上,但是當你使用了Cocoapods
后他會被clone
到本地的~/.cocoapods/repos
目錄下,可以進入到這個目錄看到master
文件夾就是這個官方的Spec Repo
了。這個master
目錄的結構是這個樣子的
.
├── Specs
└── [SPEC_NAME]
└── [VERSION]
└── [SPEC_NAME].podspec
因此我們需要創建一個類似于master
的私有Spec Repo
創建完成之后在Terminal
中執行如下命令
# pod repo add [Private Repo Name] [GitHub HTTPS clone URL]
$ pod repo add WTSpecs https://********/WTSpecs.git
此時如果成功的話進入到~/.cocoapods/repos
目錄下就可以看到WTSpecs
這個目錄了。至此第一步創建私有Spec Repo
完成。
創建Pod項目工程文件
這個第二步沒有什么好介紹的,如果是有現有的組件項目,并且在Git的版本管理下,那么這一步就算完成了,可以直接進行下一步了。
如果你的組件還在你冗余龐大的項目中,需要拆分出來或者需要自己從零開始創建一個組件庫,那么我建議你使用Cocoapods
提供的一個工具將第二步與第三步結合起來做。
創建的podTestLibrary
為例子具體講一下這里是如何操作的,先cd
到要創建項目的目錄然后執行
$ pod lib create podTestLibrary
根據提示做后續操作
創建完成后會自動執行pod install
命令創建項目并生成依賴。
$ 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
目錄
$ git add .
$ git commit -s -m "Initial Commit of Library"
$ git remote add origin git@******/podTestLibrary.git #添加遠端倉庫
$ git push origin master #提交到遠端倉庫
做完這些就可以開始編輯podspec文件了,它是一個Ruby的文件,把編輯器的格式改成Ruby就能看到語法高亮
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://********/podTestLibrary" #主頁,這里要填寫可以訪問到的地址,不然驗證不通過
# s.screenshots = "www.example.com/screenshots_1", "www.example.com/screenshots_2" #截圖
s.license = 'MIT' #開源協議
s.author = { "****" => "*****" } #作者信息
s.source = { :git => "https://******/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
是可以存在的,驗證需要執行一下命令
$ pod lib lint
當你看到
-> PodTestLibrary (0.1.0)
PodTestLibrary passed validation.
時,說明驗證通過了,不過這只是這個podspec
文件是合格的,不一定說明這個Pod
是可以用的,我們需要在本地做一下驗證,這就是第四步的內容了,第四步在具體說明。
創建podspec
文件
如果從第二步過來,已經有了現成的項目,那么就需要給這個項目創建一個podspec
文件,創建它需要執行Cocoapods
的另外一個命令,官方文檔在這里
$ pod spec create PodTestLibrary git@*******/podTestLibrary.git
執行完之后,就創建了一個podspec
文件,他其中會包含很多內容,可以按照我之前介紹的進行編輯,沒用的刪掉。編輯完成之后使用驗證命令驗證一下
$ pod lib lint
驗證無誤就可以進入下一步了。
本地測試podspec
文件
我們可以創建一個新的項目,在這個項目的Podfile
文件中直接指定剛才創建編輯好的podspec
文件,看是否可用。 在Podfile
中我們可以這樣編輯,有兩種方式
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
只需要一個命令
$ pod repo push WTSpecs PodTestLibrary.podspec #前面是本地Repo名字 后面是podspec名字
完成之后這個組件庫就添加到我們的私有Spec Repo
中了,可以進入到~/.cocoapods/repos/WTSpecs
目錄下查看
.
├── LICENSE
├── PodTestLibrary
│ └── 0.1.0
│ └── PodTestLibrary.podspec
└── README.md
再去看我們的Spec Repo
遠端倉庫,也有了一次提交,這個podspec
也已經被Push
上去了。
至此,我們的這個組件庫就已經制作添加完成了,使用pod search
命令就可以查到我們自己的庫了
$ pod search PodTestLibrary
-> PodTestLibrary (0.1.0)
Just Testing.
pod 'PodTestLibrary', '~> 0.1.0'
- Homepage: https://******/podTestLibrary
- Source: https://******/podTestLibrary.git
- Versions: 0.1.0 [WTSpecs repo]
這里說的是添加到私有的Repo
,如果要添加到Cocoapods
的官方庫了,可以使用trunk
工具,具體可以查看官方文檔
使用制作好的Pod
在完成這一系列步驟之后,我們就可以在正式項目中使用這個私有的Pod
了只需要在項目的Podfile
里增加以下一行代碼即可
$ 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
特性
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:/********/podTestLibrary"
# s.screenshots = "www.example.com/screenshots_1", "www.example.com/screenshots_2"
s.license = 'MIT'
s.author = { "******" => "*******" }
s.source = { :git => "https://*******/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
中了,命令跟之前是一樣的
$ pod repo push WTSpecs PodTestLibrary.podspec
之后再次到~/.cocoapods/repos/WTSpecs
目錄下查看
.
├── LICENSE
├── PodTestLibrary
│ ├── 0.1.0
│ │ └── PodTestLibrary.podspec
│ └── 1.0.0
│ └── PodTestLibrary.podspec
└── README.md
3 directories, 4 files
已經有兩個版本了,使用pod search
查找得到的結果為
$ pod search PodTestLibrary
-> PodTestLibrary (1.0.0)
Just Testing.
pod 'PodTestLibrary', '~> 1.0.0'
- Homepage: https://*******/podTestLibrary
- Source: https://*******/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
中添加的內容為
source 'https://github.com/CocoaPods/Specs.git' # 官方庫
source 'https://*******/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
,只需要執行一條命令即可
$ pod repo remove WTSpecs
這樣這個Spec Repo
就在本地刪除了,我們還可以通過
$ pod repo add WTSpecs git@********/WTSpecs.git
再把它給加回來。
如果我們要刪除私有Spec Repo
下的某一個podspec
怎么操作呢,此時無需借助Cocoapods
,只需要cd
到~/.cocoapods/repos/WTSpecs
目錄下,刪掉庫目錄
@MacBook-Pro:~/.cocoapods/repos/WTSpecs$ rm -Rf PodTestLibrary
然后在將Git
的變動push
到遠端倉庫即可