到新公司兩個(gè)月,公司項(xiàng)目就開始轉(zhuǎn)型,以至于需要將原來(lái)的App重寫一遍,只有其中的一個(gè)通信模塊是可以復(fù)用的,但這個(gè)模塊跟原有項(xiàng)目的耦合性太強(qiáng)。為了將來(lái)在其他項(xiàng)目中也能使用這個(gè)模塊,我們決定將這個(gè)模塊進(jìn)行剝離,用CocoaPods進(jìn)行管理。這里就涉及到了使用CocoaPods管理私有庫(kù),這也是App組件化的第一步。今天我們就一個(gè)簡(jiǎn)單例子講解私有庫(kù)的創(chuàng)建過程。里面的注意事項(xiàng)都是我這段時(shí)間所遇到的問題,還挺折騰人的。
我們現(xiàn)在要將以下工程的MyPrivateLib文件夾用cocoapods管理。注意,這個(gè)工程一定要對(duì)應(yīng)一個(gè)遠(yuǎn)程的git倉(cāng)庫(kù)。

1.創(chuàng)建私有的Spec Repo
Spec Repo是cocoapods庫(kù)的索引,所有庫(kù)都在這里面,它實(shí)際上是一個(gè)git倉(cāng)庫(kù),對(duì)應(yīng)于本地的路徑是~/.cocoapods/repos/,執(zhí)行pod search 方法的時(shí)候,實(shí)際上就是在這個(gè)路徑下面搜索的,~/.cocoapods/repos/master是cocoapods官方的Spec Repo,里面包含了幾十萬(wàn)個(gè)庫(kù)的索引,我們執(zhí)行pod setup的時(shí)候?qū)嶋H上就是將官方的Spec Repo克隆到~/.cocoapods/repos/master下面。
所以我們現(xiàn)在也創(chuàng)建一個(gè)私有的git倉(cāng)庫(kù),作為我們的Spec Repo,這里我使用Coding創(chuàng)建了一個(gè)git倉(cāng)庫(kù)。然后將這個(gè)git倉(cāng)庫(kù)添加到本地。
$ pod repo add MySpecs https://git.coding.net/zhq1992/CustomSpecRepo.git
MySpecs是本地的Spec Repo,名字可以隨意修改
這時(shí)候就能在~/.cocoapods/repos/ 下看到MySpecs文件夾。

2.創(chuàng)建PodSpec文件
PodSpec或者說(shuō)Spec描述了Pod庫(kù)的版本,一個(gè)Pod可以有很多的spec,它包含了這個(gè)庫(kù)的源代碼獲取地址,使用哪些文件,還有版本,描述等信息。podspec文件可以手動(dòng)創(chuàng)建,也可以使用pod spec create創(chuàng)建。
cd 到工程目錄下
pod spec create PrivateSpecDemo
用Xcode打開PrivateSpecDemo.podspec文件,會(huì)出現(xiàn)100多行的默認(rèn)配置和注釋,我們將其全部刪除,然后添加自己需要的配置。下面是一個(gè)podspec文件的樣例。
Pod::Spec.new do |s|
s.name = "PrivateSpecDemo" #私有庫(kù)的名稱
s.version = "0.0.2" #版本號(hào)
s.summary = "私有庫(kù)demo" #簡(jiǎn)介
s.description = <<-DESC #描述
一個(gè)cocoapods管理私有庫(kù)的樣例
DESC
s.homepage = "https://coding.net/u/zhq1992/p/PrivateSpecDemo" #項(xiàng)目主頁(yè),不是git地址
s.license = { :type => "MIT", :file => "README.md" } #開源協(xié)議,填MIT即可,文件選Readme.md
s.author = { "zhouhuanqiang" => "461416254@qq.com" } #作者
s.platform = :ios, "8.0" #支持的平臺(tái)和版本號(hào)
s.source = { :git => "https://git.coding.net/zhq1992/PrivateSpecDemo.git", :tag => "#{s.version}" } #庫(kù)的git地址,以及tag號(hào),tag號(hào)一般直接用版本號(hào)
s.source_files = 'PrivateSpecDemo/PrivateSpecDemo/MyPrivateLib/**/*.{h,m}' #庫(kù)的源文件路徑
s.resources = 'PrivateSpecDemo/PrivateSpecDemo/MyPrivateLib/MyPrivateLibResouce.bundle' #資源文件地址,資源文件最好用bundle管理,注意xib文件也是資源文件,私有庫(kù)中如果有xib,需要先編譯成nib文件,再放進(jìn)bundle中
s.requires_arc = true #是否需要ARC支持
#s.dependency "SDWebImage" #如果依賴其他第三方庫(kù),在這里添加,可以添加多個(gè)
#s.dependency "MyCustomLib" #也可以引用其他的私有庫(kù),但是在驗(yàn)證的時(shí)候要加上這個(gè)私有庫(kù)的地址
end
3.驗(yàn)證PodSpec文件
執(zhí)行以下驗(yàn)證命令
$ pod lib lint
成功的話會(huì)提示
-> PrivateSpecDemo (0.0.1)
PrivateSpecDemo passed validation.
注意:
(1)如果引用了靜態(tài)庫(kù)文件,需要在pod lib lint 后面加上--use-libraries
pod lib lint --use-libraries
(2)如果引用了其他的私有庫(kù),那么需要加上另一個(gè)私有庫(kù)的地址進(jìn)行驗(yàn)證
pod lib lint --sources=https://git.coding.net/zhq1992/zhqSpecs.git,master --use-libraries
(3)執(zhí)行 pod lib lint XXX 驗(yàn)證podspec的時(shí)候如果報(bào)錯(cuò) ,記得加上 --verbose(pod lib lint XXX --verbose) 看看報(bào)錯(cuò)的具體原因。
(4)如果報(bào)錯(cuò) xcodebuild: error: 'App.xcworkspace' does not exist, CocoaPods需要升級(jí)到最新的 1.1.1 ,CocoaPods安裝流程可以查看我的上一篇文章。
(5)升級(jí)Xcode8之后,如果出現(xiàn)
- ERROR | [iOS] unknown: Encountered an unknown error (Must be in the root of the repo (/Users/zhouhuanqiang/.cocoapods/repos/master), instead in /Users/zhouhuanqiang/Desktop/IM.) during validation.
原因是xcode8路徑改了,執(zhí)行以下命令即可解決
sudo xcode-select -switch /Applications/Xcode.app/Contents/Developer
(6)pod lib lint --quick 命令可以不編譯源文件。
4.測(cè)試podspec文件
在測(cè)試之前,首要要確保工程已經(jīng)上傳到遠(yuǎn)程倉(cāng)庫(kù)了,而且打了tag。
git add .
git commit -m "first release"
git push origin master
git tag -m "first relase" "0.0.1"
git push --tags 或 git push origin 0.0.1
在測(cè)試工程下創(chuàng)建Podfile文件,然后pod install
platform:ios,'8.0'
target 'testRepo' do
pod 'PrivateSpecDemo', :podspec => '/Users/zhouhuanqiang/Desktop/PrivateSpecDemo/PrivateSpecDemo.podspec' #指定podspec文件
end
注意
(1)編譯工程如果遇到Unable to run command 'StripNIB MyCustomView.nib' - this target might include its own product.這種錯(cuò)誤,說(shuō)明沒有將xib文件加到s.resource中。但是直接將xib拖進(jìn)bundle還是無(wú)法讀取的,需要先將xib文件編譯成nib文件,再放進(jìn)bundle中。
$ ibtool --errors --warnings --output-format human-readable-text --compile MyCustomView.nib MyCustomView.xib

(2)讀取bundle文件不能像平時(shí)一樣用[NSBundle mainBundle],應(yīng)該通過如下代碼。
// 獲取bundle
NSBundle *resourceBundle = [NSBundle bundleWithPath:[[NSBundle bundleForClass:[self class]] pathForResource:@"MyPrivateLibResouce" ofType:@"bundle"]];
self = [[resourceBundle loadNibNamed:@"MyCustomView"
owner:self
options:nil] firstObject];
// 有@2x的圖片記得加上@2x
self.picView.image = [UIImage imageWithContentsOfFile:[resourceBundle pathForResource:@"loading@2x" ofType:@"png"]];
5.向Spec Repo提交podspec
pod repo push MySpecs PrivateSpecDemo.podspec
如果有靜態(tài)庫(kù)也需要加上--use-libraries
如果出現(xiàn)報(bào)錯(cuò)
Your configuration specifies to merge with the ref 'refs/heads/master'
from the remote, but no such ref was fetched.
是因?yàn)閭}(cāng)庫(kù)沒有創(chuàng)建readme.md導(dǎo)致
6.使用私有庫(kù)
Podfile要加上遠(yuǎn)程Spec Repo的地址
source 'https://git.coding.net/zhq1992/CustomSpecRepo.git'
platform:ios,'8.0'
target 'testRepo' do
pod 'PrivateSpecDemo'
end
7.更新私有庫(kù)
私有庫(kù)有更新時(shí),只要更新一下代碼和podspec文件的版本號(hào)即可,重復(fù)上述步驟。然后在測(cè)試工程里pod update (庫(kù)名)
如果有需要的話,可以去我的github里面下載示例代碼作為參考。
代碼下載地址