前言
CocoaPods是一個程序依賴管理工具,使用CocoaPods可以節省設置和更新第三方開源庫的時間,同樣的也可以利用CocoaPods來管理我們的私有庫。以下使用CocoaPods管理私有庫的方法是以安裝了CocoaPods為前提條件的。CocoaPods的安裝可查看這篇blog
正題
一、使用CocoaPods管理私有庫的方法包括如下幾個步驟:
1.創建并設置一個私有的Spec Repo
2.創建Pod
所需要的項目工程文件,并且有可訪問的項目版本控制地址。
3.創建Pod
所對應的podspec
文件。
4.本地測試配置好的podspec
文件是否可用。
5.向私有的Spec Repo
中提交podspec
6.在個人項目中的Podfile
文件里增加自己私有庫的Pod
并使用。
在這一系列步驟中需要創建兩個Git
倉庫,分別是第一步和第二步(第二步不一定非要Git
倉庫,只要是可以獲取到相關代碼文件就可以,也可以是SVN
等,區別只在于podspec
文件中的source
配置項所填寫的內容不同),并且第一步只是在初次創建私有podspec
時才需要,之后在創建其他的只需要從第二步開始就可以。本文以在Git
環境下的操作為例做介紹。
二、下面來逐步介紹整個流程:
1.創建私有的Spec Repo
先說第一步,什么是Spec Repo
?他是所有的Pods
的一個索引,也就是一個容器,所有公開的Pods
都在這個里面,它實際是一個Git倉庫的remote
端在GitHub上,當你使用了CocoaPods
后它會被clone到本地的~/.cocoapods/repos
目錄下,可以進入到這個目錄看到master文件夾就是這個官方的Spec Repo
了。所有官方公共的Pods所對應的podspec
文件都在這個路徑下的Specs文件夾下。
因此我們需要創建一個類似于master的私有Spec Repo
,這里我們可以fork官方的Repo,也可以自己創建,個人建議不fork,因為你只是想添加自己的的Pods,沒有必要把現有的公開Pods都copy一份。所以創建一個Git倉庫,這個倉庫你可以創建私有的也可以創建公開的,不過既然私有的Spec Repo
,還是創建私有的倉庫吧,需要注意的就是如果項目中有其他同事共同開發的話,你還要給他這個Git倉庫的權限。
創建完成后在終端中執行以下命令:
pod repo add [Private Repo Name] [GitHub HTTPS clone URL]
此時如果成功的話進入到~/.cocoapods/repos
目錄下就可以看到YourSpecs
這個目錄了。至此第一步創建私有Spec Repo
完成。
PS:如果有其他合作人員共同使用這個私有 Spec Repo
的話在他有對應Git倉庫的權限的前提下執行相同的命令添加這個Spec Repo
即可。
2.創建Pod項目工程文件
第二步沒有什么好介紹的,如果是有現有的組件項目,并且在Git的版本管理下,那么這一步就算完成了,可以直接進行下一步了。
如果你的組件還在你冗余龐大的項目中,需要拆分出來或者需要自己從零開始創建一個組件庫,那么我建議你使用Cocoapods提供的一個工具將第二步與第三步結合起來做。現在來說一下這個工具,相關的文檔介紹可以查看這里,我們重新創建一個工程YourPodTestLibrary
為例,來具體講一下是如何操作的,
先cd到要創建項目的目錄,我就cd到桌面,
然后執行命令: pod lib create YourPodTestLibrary
之后會出現幾個問題:
1.你希望使用那種開發語言?
2.是否需要一個Demo工程?
3.需要使用哪種測試框架?
4.是否需要基于視圖的測試?
5.你的類以什么為前綴?
選擇以后,問完這幾個問題它會自動執行pod install創建項目并生成依賴。創建完成后的工程和文件夾內容看上去應該像是這樣的:
接下來就是向YourPodTestLibrary
文件夾中添加庫文件和資源,并配置podspec
文件。我新建一個名為YourPodTestLibraryDemoFile
繼承自NSObject
的類,包含.h和.m兩個文件,放入到YourPodTestLibrary/Classes
中,然后進入Example
文件夾執行pod update
命令,再打開項目工程可以看到,剛剛添加的YourPodTestLibraryDemoFile
文件已經在Pods子工程下的Development Pods/YourPodTestLibrary
中了。
查看無誤后需要將該項目添加并推送到遠端倉庫,并編輯podspec
文件。通過Cocoapods
創建出來的目錄本身就在本地的Git管理下,我們需要做的就是給它添加遠端倉庫,同樣去GitHub或其他的Git服務提供商那里創建一個私有的倉庫,拿到SSH地址,然后cd到YourPodTestLibrary
目錄執行以下命令:
git add . #這里有個"."別漏了
git commit -s -m "Initial Commit of Library"
git remote add origin git@github.com:username/YourPodTestLibrary.git #添加遠端Git倉庫SSH地址
git push origin master #提交到遠端倉庫
這樣項目就提交到GitHub上了。
因為podspec
文件中獲取Git版本控制的項目還需要tag
號,所以我們要打上一個tag
,再執行以下命令:
git tag -m "first release" 0.1.0
git push --tags #推送tag到遠端倉庫
3.編輯podspec文件
上傳完工程后就可以開始編輯podspec
文件了,這里是YourPodTestLibrary.podspec
文件,它是一個Ruby文件,用SubLime打開它,把編輯格式改成Ruby就能看到語法高亮了,原始的podspec
文件已經有很多內容了,其中以#
開頭的都是被注釋掉的部分,看起來應該像下圖所示:
Pod::Spec.new do |s|
s.name = 'FCBaseLibary'
s.version = '0.0.5'
s.summary = 'FCBaseLibary.'
# s.screenshots = 'www.example.com/screenshots_1', 'www.example.com/screenshots_2'
s.description = <<-DESC
TODO: Add long description of the pod here.
DESC
s.homepage = 'https://git.xxxx.com/'
s.license = { :type => 'MIT', :file => 'LICENSE' }
s.author = { 'dennis' => 'dennis@awesomedennis.com' }
s.source = { :git => "http://git.xxxx.com/ios/app/iOSRepo.git", :tag => "#{s.version}" ,:submodules => true}
s.ios.deployment_target = '7.0'
s.platform = :ios, "7.0"
# s.source_files = 'FCBaseLibary/Classes/**/*'
# s.public_header_files = 'FCBaseLibary/Classes/**/*.h'
s.subspec 'FCCache' do |fccache|
fccache.source_files = "FCBaseLibary/Classes/FCCache/*.{h,m,mm,c}"
fccache.public_header_files = "FCBaseLibary/Classes/FCCache/*.h"
end
end
下面是編輯完成后的podspec
文件,每個配置項后面都添加上了注釋:
編輯完podspec文件后,需要驗證一下這個文件是否可用,如果有任何warning
或者error
都是不可以的,它就不能被添加到Spec Repo
中。驗證需要執行以下命令:
pod lib lint
當你看到
表示驗證通過了,不過這只是說明這個podspec
文件是合格的,不一定說明這個Pod是可用的,我們需要在本地做一下驗證,這就是第四步要做的內容了。
4.本地測試podspec
文件
我們可以創建一個新的項目,在這個項目的Podfile文件中直接指定剛才創建編輯好的podspec
文件,查看是否可用。在Podfile中我們可以這樣編寫,有兩種方式:
pod 'PodTestLibrary', :path => '/Users/username/Desktop/YourPodTestLibrary' // 指定本地路徑
pod 'PodTestLibrary', :podspec => '/Users/username/Desktop/YourPodTestLibrary/YourPodTestLibrary.podspec' // 指定本地podspec文件路徑
然后執行pod install
命令安裝依賴,打開項目工程,可以看到庫文件都被加載到Pods
子項目中了,不過它們并沒有在Pods
目錄下,而是跟測試項目一樣存在于Development Pods/PodTestLibrary
中,這是因為我們是在本地測試,而沒有把podspec
文件添加到Spec Repo
中的緣故。
5.向Spec Repo
提交podspec
向Spec Repo
提交podspec
需要完成兩點,一個是podspec
必須通過驗證無誤,再一個就是刪掉無用的注釋(這個不是必須的,為了規范還是刪掉吧)。向我們的私有Spec Repo
提交podspec
文件只需要一個命令,先cd
到podspec
文件所在的目錄,然后執行:
pod repo push YourSpecs YourPodTestLibrary.podspec // 前面是本地Repo名字 后面是podspec文件的名字
當你看到終端顯示這樣的提示后,表示podspec
文件上傳成功了,同時這個組件庫也就添加到我們的私有Spec Repo
中了:
完成后可以進入到~/.cocoapods/repos
目錄中查看到我們私有的Spec Repo
了,并且在YourSpecs
這個私有Repo中已經有一個0.1.0
版本的podspec
文件了,如下圖:
再去看我們在GitHub上為我們私有的Spec Repo
創建的遠端倉庫,已經有了一次提交,這個podspec
文件也已經被push
到倉庫中了。
至此,我們的這個私有組件庫就已經制作添加完成了,使用pod search
命令就可以查到我們自己的庫了:
這里說的是添加到私有的Repo
,如果要添加到Cocoapods
的官方庫,可以使用trunk
工具,具體可以查看官方文檔
6.使用制作好的pod
在完成這一系列步驟之后,我們就可以在正式項目中使用這個私有的pod
了,只需要在項目的podfile
文件里增加以下兩行代碼即可:
source 'https://github.com/username/YourSpecs.git' // 制定pod對應的pod spec文件所在的源,切記要在自己的私有庫前制定source地址!!!
pod 'YourPodTestLibrary'
然后執行pod install
命令安裝庫依賴,然后打開項目可以看到,我們自己的庫文件已經出現在Pods
子項目中的Pods目錄下了,而不是在Development Pods
。
更新和維護自己的podspec
最后再來說一下制作好的podspec文件后續的更新和維護工作要如何進行,比如要如何添加新的版本,如何刪除Pod等。我們之前已經制作好了YourPodTestLibrary
的0.1.0
版本,現在我們對它進行升級工作,這次我添加了更多的模塊到YourPodTestLibrary
之中,包括工具類,底層Model
及UIKit
擴展等,這里又嘗試了一下subspec
功能,給YourPodTestLibrary
創建了多個分支。
具體做法是先將源文件添加到YourPodTestLibrary/Classes
中,然后按照不同的模塊對文件目錄進行整理,因為有四個模塊,所以在YourPodTestLibrary/Classes
下又創建了四個子目錄,完成之后繼續編輯之前的YourPodTestLibrary.podspec
文件,這次增加了subspec
屬性,變更了podspec
文件的版本號和私有庫的tag
,其它配置項不變。
Pod::Spec.new do |s|
s.name = 'FCBaseLibary'
s.version = '0.0.5'
s.summary = 'FCBaseLibary.'
s.description = <<-DESC
TODO: Add long description of the pod here.
DESC
s.homepage = 'https://git.xxxx.com/'
s.license = { :type => 'MIT', :file => 'LICENSE' }
s.author = { 'dennis' => 'dennis@awesomedennis.com' }
s.source = { :git => "http://git.xxxx.com/ios/app/iOSRepo.git", :tag => "#{s.version}" ,:submodules => true}
s.ios.deployment_target = '7.0'
s.platform = :ios, "7.0"
# s.source_files = 'FCBaseLibary/Classes/**/*'
# s.public_header_files = 'FCBaseLibary/Classes/**/*.h'
s.subspec 'FCCache' do |fccache|
fccache.source_files = "FCBaseLibary/Classes/FCCache/*.{h,m,mm,c}"
fccache.public_header_files = "FCBaseLibary/Classes/FCCache/*.h"
end
s.subspec 'FCCategory' do |fccategory|
fccategory.source_files = "FCBaseLibary/Classes/FCCategory/*.{h,m,mm,c}"
fccategory.public_header_files = "FCBaseLibary/Classes/FCCategory/*.h"
fccategory.dependency "FCBaseLibary/FCPublicMethods"
end
s.subspec 'FCImage' do |fcimage|
fcimage.source_files = "FCBaseLibary/Classes/FCImage/*.{h,m,mm,c}"
fcimage.public_header_files = "FCBaseLibary/Classes/FCImage/*.h"
end
s.subspec 'FCPublicMethods' do |fcpublicMethods|
fcpublicMethods.source_files = "FCBaseLibary/Classes/FCPublicMethods/*.{h,m,mm,c}"
fcpublicMethods.public_header_files = "FCBaseLibary/Classes/FCPublicMethods/*.h"
end
s.subspec 'FCThreeDES' do |fcthreeDES|
fcthreeDES.source_files = "FCBaseLibary/Classes/FCThreeDES/*.{h,m,mm,c}"
fcthreeDES.public_header_files = "FCBaseLibary/Classes/FCThreeDES/*.h"
end
s.subspec 'HPGrowingTextView' do |hpgrowingTextView|
hpgrowingTextView.source_files = "FCBaseLibary/Classes/HPGrowingTextView/*.{h,m,mm,c}"
hpgrowingTextView.public_header_files = "FCBaseLibary/Classes/HPGrowingTextView/*.h"
end
s.subspec 'PinyinSort' do |pinyinSort|
pinyinSort.source_files = "FCBaseLibary/Classes/PinyinSort/*.{h,m,mm,c}"
pinyinSort.public_header_files = "FCBaseLibary/Classes/PinyinSort/*.h"
end
s.frameworks = 'UIKit', 'Foundation', 'WebKit', 'CoreTelephony'
s.requires_arc = true
s.dependency 'SDWebImage', '3.7.5'
s.dependency 'MBProgressHUD', '0.9.2'
end
因為我們創建了subspec
所以項目整體的依賴,dependency
,源文件source_file
,頭文件public_header_files
,資源文件resouece
等都移動到了各自的subspec
中,每個subspec
之間也可以有相互的依賴關系,比如FCCategory
就依賴于FCPublicMethods
。
編輯完成之后,在測試項目里pod update
一下,幾個子項目都被加進項目工程了,查看無誤就可以將新增的庫文件push到遠端倉庫,并打上新的tag->1.0.0
最后再次使用pod lib lint
驗證新編輯好的podspec
文件,沒有自身的warning或者error之后,就可以再次提交到Spec Repo中了,命令跟之前的是一樣的:
驗證通過,上傳成功之后,再次到~/.cocoapods/repos/YourPodTestLibrary/
目錄下查看,發現已經有0.1.0和1.0.0兩個版本了:
使用pod search
命令查看私有庫的結果是:
完成這些之后,在實際項目中我們就可以選擇使用整個組件庫或者是組件庫的某一個部分了,對應的podfile
中添加的內容為:
最后介紹一下如何刪除一個私有Spec Repo
,只需要執行一條命令即可
pod repo remove [Private Repo Name]
這樣這個Spec Repo就在本地刪除了,我們還是可以通過
pod repo add [Private Repo Name] [GitHub HTTPS clone URL]
再把它加回來。
如果我們要刪除私有的Spec Repo
下的某個podspec
要怎么操作呢?此時無需借助CocoaPods
,只需要cd到對應的Spec Repo目錄下,如:~/.cocoapods/repos/YourSpecs/
目錄,刪除庫目錄:
rm -Rf YourPodTestLibrary
然后將git的變動push到遠端倉庫即可:
git add --all . #這里有個"."別漏了
git ci -m "remove unuseful pods"
git push origin master
關于'pod lint'的補充說明
在開發的過程中,不可避免,我們會遇到一些警告(好多代碼壓根不是自己寫的,實在無法維護 - -)的情況,出于代碼潔癖,就是想lint 過一下。可以采用如下方式
pod lib lint --private --use-libraries --allow-warnings
在這里解釋說明一下吧:
- --private 代表私有
- --use-libraries 解決因為引入其他framework造成的無法通過
- --allow-warnings 允許警告
其他,還是要看具體報錯的信息了。use google stackoverflow. - 解決引入.pch
歡迎補充。??