
前言
CocoaPods是一個(gè)程序依賴管理工具,使用CocoaPods可以節(jié)省設(shè)置和更新第三方開(kāi)源庫(kù)的時(shí)間,同樣的也可以利用CocoaPods來(lái)管理我們的私有庫(kù)。以下使用CocoaPods管理私有庫(kù)的方法是以安裝了CocoaPods為前提條件的。CocoaPods的安裝可查看這篇blog
正題
一、使用CocoaPods管理私有庫(kù)的方法包括如下幾個(gè)步驟:
1.創(chuàng)建并設(shè)置一個(gè)私有的Spec Repo
2.創(chuàng)建Pod所需要的項(xiàng)目工程文件,并且有可訪問(wèn)的項(xiàng)目版本控制地址。
3.創(chuàng)建Pod所對(duì)應(yīng)的podspec文件。
4.本地測(cè)試配置好的podspec文件是否可用。
5.向私有的Spec Repo中提交podspec
6.在個(gè)人項(xiàng)目中的Podfile文件里增加自己私有庫(kù)的Pod并使用。
在這一系列步驟中需要?jiǎng)?chuàng)建兩個(gè)Git倉(cāng)庫(kù),分別是第一步和第二步(第二步不一定非要Git倉(cāng)庫(kù),只要是可以獲取到相關(guān)代碼文件就可以,也可以是SVN等,區(qū)別只在于podspec文件中的source配置項(xiàng)所填寫(xiě)的內(nèi)容不同),并且第一步只是在初次創(chuàng)建私有podspec時(shí)才需要,之后在創(chuàng)建其他的只需要從第二步開(kāi)始就可以。本文以在Git環(huán)境下的操作為例做介紹。
二、下面來(lái)逐步介紹整個(gè)流程:
1.創(chuàng)建私有的Spec Repo
先說(shuō)第一步,什么是Spec Repo?他是所有的Pods的一個(gè)索引,也就是一個(gè)容器,所有公開(kāi)的Pods都在這個(gè)里面,它實(shí)際是一個(gè)Git倉(cāng)庫(kù)的remote端在GitHub上,當(dāng)你使用了CocoaPods后它會(huì)被clone到本地的~/.cocoapods/repos目錄下,可以進(jìn)入到這個(gè)目錄看到master文件夾就是這個(gè)官方的Spec Repo了。所有官方公共的Pods所對(duì)應(yīng)的podspec文件都在這個(gè)路徑下的Specs文件夾下。
因此我們需要?jiǎng)?chuàng)建一個(gè)類似于master的私有Spec Repo,這里我們可以fork官方的Repo,也可以自己創(chuàng)建,個(gè)人建議不fork,因?yàn)槟阒皇窍胩砑幼约旱牡腜ods,沒(méi)有必要把現(xiàn)有的公開(kāi)Pods都copy一份。所以創(chuàng)建一個(gè)Git倉(cāng)庫(kù),這個(gè)倉(cāng)庫(kù)你可以創(chuàng)建私有的也可以創(chuàng)建公開(kāi)的,不過(guò)既然私有的Spec Repo,還是創(chuàng)建私有的倉(cāng)庫(kù)吧,需要注意的就是如果項(xiàng)目中有其他同事共同開(kāi)發(fā)的話,你還要給他這個(gè)Git倉(cāng)庫(kù)的權(quán)限。
創(chuàng)建完成后在終端中執(zhí)行以下命令:
pod repo add [Private Repo Name] [GitHub HTTPS clone URL]
此時(shí)如果成功的話進(jìn)入到~/.cocoapods/repos目錄下就可以看到YourSpecs這個(gè)目錄了。至此第一步創(chuàng)建私有Spec Repo完成。
PS:如果有其他合作人員共同使用這個(gè)私有 Spec Repo的話在他有對(duì)應(yīng)Git倉(cāng)庫(kù)的權(quán)限的前提下執(zhí)行相同的命令添加這個(gè)Spec Repo即可。
2.創(chuàng)建Pod項(xiàng)目工程文件
第二步?jīng)]有什么好介紹的,如果是有現(xiàn)有的組件項(xiàng)目,并且在Git的版本管理下,那么這一步就算完成了,可以直接進(jìn)行下一步了。
如果你的組件還在你冗余龐大的項(xiàng)目中,需要拆分出來(lái)或者需要自己從零開(kāi)始創(chuàng)建一個(gè)組件庫(kù),那么我建議你使用Cocoapods提供的一個(gè)工具將第二步與第三步結(jié)合起來(lái)做?,F(xiàn)在來(lái)說(shuō)一下這個(gè)工具,相關(guān)的文檔介紹可以查看這里,我們重新創(chuàng)建一個(gè)工程YourPodTestLibrary為例,來(lái)具體講一下是如何操作的,
先cd到要?jiǎng)?chuàng)建項(xiàng)目的目錄,我就cd到桌面,
然后執(zhí)行命令: pod lib create YourPodTestLibrary
之后會(huì)出現(xiàn)幾個(gè)問(wèn)題:
1.你希望使用那種開(kāi)發(fā)語(yǔ)言?
2.是否需要一個(gè)Demo工程?
3.需要使用哪種測(cè)試框架?
4.是否需要基于視圖的測(cè)試?
5.你的類以什么為前綴?
選擇以后,問(wèn)完這幾個(gè)問(wèn)題它會(huì)自動(dòng)執(zhí)行pod install創(chuàng)建項(xiàng)目并生成依賴。創(chuàng)建完成后的工程和文件夾內(nèi)容看上去應(yīng)該像是這樣的:
接下來(lái)就是向YourPodTestLibrary文件夾中添加庫(kù)文件和資源,并配置podspec文件。我新建一個(gè)名為YourPodTestLibraryDemoFile繼承自NSObject的類,包含.h和.m兩個(gè)文件,放入到YourPodTestLibrary/Classes中,然后進(jìn)入Example文件夾執(zhí)行pod update命令,再打開(kāi)項(xiàng)目工程可以看到,剛剛添加的YourPodTestLibraryDemoFile文件已經(jīng)在Pods子工程下的Development Pods/YourPodTestLibrary中了。
查看無(wú)誤后需要將該項(xiàng)目添加并推送到遠(yuǎn)端倉(cāng)庫(kù),并編輯podspec文件。通過(guò)Cocoapods創(chuàng)建出來(lái)的目錄本身就在本地的Git管理下,我們需要做的就是給它添加遠(yuǎn)端倉(cāng)庫(kù),同樣去GitHub或其他的Git服務(wù)提供商那里創(chuàng)建一個(gè)私有的倉(cāng)庫(kù),拿到SSH地址,然后cd到YourPodTestLibrary目錄執(zhí)行以下命令:
git add . #這里有個(gè)"."別漏了
git commit -s -m "Initial Commit of Library"
git remote add origin git@github.com:username/YourPodTestLibrary.git #添加遠(yuǎn)端Git倉(cāng)庫(kù)SSH地址
git push origin master #提交到遠(yuǎn)端倉(cāng)庫(kù)
這樣項(xiàng)目就提交到GitHub上了。
因?yàn)?code>podspec文件中獲取Git版本控制的項(xiàng)目還需要tag號(hào),所以我們要打上一個(gè)tag,再執(zhí)行以下命令:
git tag -m "first release" 0.1.0
git push --tags #推送tag到遠(yuǎn)端倉(cāng)庫(kù)
3.編輯podspec文件
上傳完工程后就可以開(kāi)始編輯podspec文件了,這里是YourPodTestLibrary.podspec文件,它是一個(gè)Ruby文件,用SubLime打開(kāi)它,把編輯格式改成Ruby就能看到語(yǔ)法高亮了,原始的podspec文件已經(jīng)有很多內(nèi)容了,其中以#開(kāi)頭的都是被注釋掉的部分,看起來(lái)應(yīng)該像下圖所示:
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文件,每個(gè)配置項(xiàng)后面都添加上了注釋:
編輯完podspec文件后,需要驗(yàn)證一下這個(gè)文件是否可用,如果有任何warning或者error都是不可以的,它就不能被添加到Spec Repo中。驗(yàn)證需要執(zhí)行以下命令:
pod lib lint
當(dāng)你看到
表示驗(yàn)證通過(guò)了,不過(guò)這只是說(shuō)明這個(gè)podspec文件是合格的,不一定說(shuō)明這個(gè)Pod是可用的,我們需要在本地做一下驗(yàn)證,這就是第四步要做的內(nèi)容了。
4.本地測(cè)試podspec文件
我們可以創(chuàng)建一個(gè)新的項(xiàng)目,在這個(gè)項(xiàng)目的Podfile文件中直接指定剛才創(chuàng)建編輯好的podspec文件,查看是否可用。在Podfile中我們可以這樣編寫(xiě),有兩種方式:
pod 'PodTestLibrary', :path => '/Users/username/Desktop/YourPodTestLibrary' // 指定本地路徑
pod 'PodTestLibrary', :podspec => '/Users/username/Desktop/YourPodTestLibrary/YourPodTestLibrary.podspec' // 指定本地podspec文件路徑
然后執(zhí)行pod install命令安裝依賴,打開(kāi)項(xiàng)目工程,可以看到庫(kù)文件都被加載到Pods子項(xiàng)目中了,不過(guò)它們并沒(méi)有在Pods目錄下,而是跟測(cè)試項(xiàng)目一樣存在于Development Pods/PodTestLibrary中,這是因?yàn)槲覀兪窃诒镜販y(cè)試,而沒(méi)有把podspec文件添加到Spec Repo中的緣故。
5.向Spec Repo提交podspec
向Spec Repo提交podspec需要完成兩點(diǎn),一個(gè)是podspec必須通過(guò)驗(yàn)證無(wú)誤,再一個(gè)就是刪掉無(wú)用的注釋(這個(gè)不是必須的,為了規(guī)范還是刪掉吧)。向我們的私有Spec Repo提交podspec文件只需要一個(gè)命令,先cd到podspec文件所在的目錄,然后執(zhí)行:
pod repo push YourSpecs YourPodTestLibrary.podspec // 前面是本地Repo名字 后面是podspec文件的名字
當(dāng)你看到終端顯示這樣的提示后,表示podspec文件上傳成功了,同時(shí)這個(gè)組件庫(kù)也就添加到我們的私有Spec Repo中了:
完成后可以進(jìn)入到~/.cocoapods/repos目錄中查看到我們私有的Spec Repo了,并且在YourSpecs這個(gè)私有Repo中已經(jīng)有一個(gè)0.1.0版本的podspec文件了,如下圖:

再去看我們?cè)贕itHub上為我們私有的Spec Repo創(chuàng)建的遠(yuǎn)端倉(cāng)庫(kù),已經(jīng)有了一次提交,這個(gè)podspec文件也已經(jīng)被push到倉(cāng)庫(kù)中了。
至此,我們的這個(gè)私有組件庫(kù)就已經(jīng)制作添加完成了,使用pod search命令就可以查到我們自己的庫(kù)了:
這里說(shuō)的是添加到私有的Repo,如果要添加到Cocoapods的官方庫(kù),可以使用trunk工具,具體可以查看官方文檔
6.使用制作好的pod
在完成這一系列步驟之后,我們就可以在正式項(xiàng)目中使用這個(gè)私有的pod了,只需要在項(xiàng)目的podfile文件里增加以下兩行代碼即可:
source 'https://github.com/username/YourSpecs.git' // 制定pod對(duì)應(yīng)的pod spec文件所在的源,切記要在自己的私有庫(kù)前制定source地址?。。?pod 'YourPodTestLibrary'
然后執(zhí)行pod install命令安裝庫(kù)依賴,然后打開(kāi)項(xiàng)目可以看到,我們自己的庫(kù)文件已經(jīng)出現(xiàn)在Pods子項(xiàng)目中的Pods目錄下了,而不是在Development Pods。
更新和維護(hù)自己的podspec
最后再來(lái)說(shuō)一下制作好的podspec文件后續(xù)的更新和維護(hù)工作要如何進(jìn)行,比如要如何添加新的版本,如何刪除Pod等。我們之前已經(jīng)制作好了YourPodTestLibrary的0.1.0版本,現(xiàn)在我們對(duì)它進(jìn)行升級(jí)工作,這次我添加了更多的模塊到YourPodTestLibrary之中,包括工具類,底層Model及UIKit擴(kuò)展等,這里又嘗試了一下subspec功能,給YourPodTestLibrary創(chuàng)建了多個(gè)分支。
具體做法是先將源文件添加到YourPodTestLibrary/Classes中,然后按照不同的模塊對(duì)文件目錄進(jìn)行整理,因?yàn)橛兴膫€(gè)模塊,所以在YourPodTestLibrary/Classes下又創(chuàng)建了四個(gè)子目錄,完成之后繼續(xù)編輯之前的YourPodTestLibrary.podspec文件,這次增加了subspec屬性,變更了podspec文件的版本號(hào)和私有庫(kù)的tag,其它配置項(xiàng)不變。
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
因?yàn)槲覀儎?chuàng)建了subspec所以項(xiàng)目整體的依賴,dependency,源文件source_file,頭文件public_header_files,資源文件resouece等都移動(dòng)到了各自的subspec中,每個(gè)subspec之間也可以有相互的依賴關(guān)系,比如FCCategory就依賴于FCPublicMethods。
編輯完成之后,在測(cè)試項(xiàng)目里pod update一下,幾個(gè)子項(xiàng)目都被加進(jìn)項(xiàng)目工程了,查看無(wú)誤就可以將新增的庫(kù)文件push到遠(yuǎn)端倉(cāng)庫(kù),并打上新的tag->1.0.0
最后再次使用pod lib lint驗(yàn)證新編輯好的podspec文件,沒(méi)有自身的warning或者error之后,就可以再次提交到Spec Repo中了,命令跟之前的是一樣的:
驗(yàn)證通過(guò),上傳成功之后,再次到~/.cocoapods/repos/YourPodTestLibrary/目錄下查看,發(fā)現(xiàn)已經(jīng)有0.1.0和1.0.0兩個(gè)版本了:
使用pod search命令查看私有庫(kù)的結(jié)果是:
完成這些之后,在實(shí)際項(xiàng)目中我們就可以選擇使用整個(gè)組件庫(kù)或者是組件庫(kù)的某一個(gè)部分了,對(duì)應(yīng)的podfile中添加的內(nèi)容為:
最后介紹一下如何刪除一個(gè)私有Spec Repo,只需要執(zhí)行一條命令即可
pod repo remove [Private Repo Name]
這樣這個(gè)Spec Repo就在本地刪除了,我們還是可以通過(guò)
pod repo add [Private Repo Name] [GitHub HTTPS clone URL]
再把它加回來(lái)。
如果我們要?jiǎng)h除私有的Spec Repo下的某個(gè)podspec要怎么操作呢?此時(shí)無(wú)需借助CocoaPods,只需要cd到對(duì)應(yīng)的Spec Repo目錄下,如:~/.cocoapods/repos/YourSpecs/目錄,刪除庫(kù)目錄:
rm -Rf YourPodTestLibrary
然后將git的變動(dòng)push到遠(yuǎn)端倉(cāng)庫(kù)即可:
git add --all . #這里有個(gè)"."別漏了
git ci -m "remove unuseful pods"
git push origin master
關(guān)于'pod lint'的補(bǔ)充說(shuō)明
在開(kāi)發(fā)的過(guò)程中,不可避免,我們會(huì)遇到一些警告(好多代碼壓根不是自己寫(xiě)的,實(shí)在無(wú)法維護(hù) - -)的情況,出于代碼潔癖,就是想lint 過(guò)一下??梢圆捎萌缦路绞?/p>
pod lib lint --private --use-libraries --allow-warnings
在這里解釋說(shuō)明一下吧:
- --private 代表私有
- --use-libraries 解決因?yàn)橐肫渌鹒ramework造成的無(wú)法通過(guò)
- --allow-warnings 允許警告
其他,還是要看具體報(bào)錯(cuò)的信息了。use google stackoverflow. - 解決引入.pch
歡迎補(bǔ)充。??