項(xiàng)目更新到一定的階段,工程越來越大,編譯時(shí)間越來越長,我們一般會將項(xiàng)目抽取成一個(gè)個(gè)的組件,組件一般都會使用cocoaPods 來制作成私有庫來相互引用,話不多說,第一次的制作,真是一步一個(gè)坑,這里做個(gè)總結(jié):
制作私有庫,一定要創(chuàng)建兩個(gè)倉庫 一個(gè)存放私有的
PodSpesc
,另一個(gè)倉庫存放私有的組件代碼。
這個(gè)很重要 ,,很重要,, 很重要。。
(一開始不知道,被坑了好久。。)默認(rèn)的
podSpesc
是放在官方倉庫的,我們是私有庫,不想被別人使用,所以需要單獨(dú)創(chuàng)建一個(gè)podSpesc
倉庫
1, 先創(chuàng)建podSpesc
倉庫,因?yàn)槭撬接械模覀円话氵x擇 coding
, 碼云
,gitLab
等git倉庫。因?yàn)樗接械拿赓M(fèi)。。 我們公司選擇的是gitLab ,所以這里以GitLab 做示例;
將私有的這個(gè)podSpesc 關(guān)聯(lián)到本地,
// 我們先查詢當(dāng)前本地的pod 庫,一般會有一個(gè)master
這個(gè)是cocoaPods
官方的repo
$ pod repo
將我們創(chuàng)建的倉庫添加到本地?zé)醨epo里,
$ pod repo add QFPodSpec http://xxxxx.com/xxxt/QFPodSpec.git
3E86F43E-33C9-446F-A3AC-B726DA0BFA54.png
$ pod repo
可以發(fā)現(xiàn)我們本地的repo里多了個(gè)QFPodSpec
QQ20180804-114719@2x.png
至此,我們第一步,創(chuàng)建私有的spec倉庫算是完成,現(xiàn)在開始創(chuàng)建私有的組件工程。
使用 pod 命令創(chuàng)建一個(gè)模板工程。
$ pod lib create 項(xiàng)目名稱
在創(chuàng)建的過程中會詢問你四個(gè)問題,
What platform do you want to use?? [ iOS / macOS ]
iOS
What language do you want to use?? [ Swift / ObjC ]
ObjC
Would you like to include a demo application with your library? [ Yes / No ]
Which testing frameworks will you use? [ Specta / Kiwi / None ]
What is your class prefix?
看自己需求回答。
克隆完成之后,會自動打開工程。
工程結(jié)構(gòu)如下:
我們的項(xiàng)目文件需要放在,Classes
文件夾下;
這里我添加了一些項(xiàng)目中常用的小工具
進(jìn)入到
Example
文件夾路徑下, 執(zhí)行
$ pod update
執(zhí)行完畢后打開
Example
工程。編譯運(yùn)行,如果存在錯(cuò)誤,需要解決掉。
可以發(fā)現(xiàn)我們添加的文件被放在了Development Pods
文件下
QQ20180804-120759@2x.png
確認(rèn)編譯通過后,開始修改工程的,
.podspec
文件
podspec
是我們私有庫的描述文件,
QQ20180804-121149@2x.png
注意:s.verison
必須要跟我們私有庫的tag 保持一致。
s.description
必須要修改
s.source
修改成私有庫的地址。
由于
podspec
需要填寫私有庫的地址,這里我們創(chuàng)建一個(gè)私有庫倉庫。
將倉庫地址替換掉
s.source
路徑,pod 是根據(jù)這個(gè)地址來索引我們的私有庫的。
所有的修改完畢之后,我們將修改提交到代碼倉庫。
cd 到當(dāng)前項(xiàng)目路徑
// 查看當(dāng)前文件狀態(tài)
git status
// 提交修改文件
git add .
git commit -m '修改說明'
// 查看當(dāng)前遠(yuǎn)程倉庫
git remote // 當(dāng)前我們還沒有添加,所有是空的,
// 添加遠(yuǎn)程倉庫
git remote add origin 倉庫地址,//(我們剛創(chuàng)建的QFCommon的倉庫地址)
// 推送到遠(yuǎn)程倉庫
git push origin master
// 給我們的修改打上tag
(再說一遍這里的tag 一定要和podspec 里的s.version 保持一致)
git tag -a 0.0.1 -m '0.0.1'
// 推送tag
git push --tags
至此,我們的遠(yuǎn)程倉庫里已經(jīng)有了工程并且也已經(jīng)打上了tag。
下一步 我們就需要將podSpec 上傳到我們的私有倉庫里。
我們先在本地驗(yàn)證當(dāng)前的podspec 是否合法
$ pod lib lint QFCommon.podspec --allow-warnings
// --allow-warnings 忽略掉相應(yīng)的警告,
如果有錯(cuò)誤,可以加上,
pod lib lint QFCommon.podspec --allow-warnings --verbose
// --verbose 查看詳細(xì)分析信息。(這里踩坑無數(shù),待會再說)
// 如果當(dāng)前的私有庫依賴了其他的私有庫,需要添加私有庫的spec的地址,
pod lib lint QFCommon.podspec --sources=http://xxxx/xxx/myPodSpec.git,https://github.com/CocoaPods/Specs.git --allow-warnings --use-libraries
// 當(dāng)私有庫里引用了第三方的靜態(tài)庫,需要添加 --use-libraries
當(dāng)看到QFCommon passed validation.
表示驗(yàn)證通過。
驗(yàn)證通過后,我們開始上傳到我們的遠(yuǎn)程倉庫(驗(yàn)證通過,不代表上傳就一定能過,這里也有坑。。)
// 上傳我們的podspec 到私有的倉庫
$ pod repo push QFPodSpec QFCommon.podspec --allow-warnings
// 如果依賴了私有庫,在上傳時(shí),同樣需要添加上--sources= 路徑
!!!!! 這里一定要分清
QFPodSpec
是我們創(chuàng)建的私有的podspec 倉庫名稱,QFCommon.podspec
是我們組件的描述文件的podspec. 一定分清 ,分清,分清,, !!!!!!
如果上傳成功的話,在遠(yuǎn)程倉庫里就可以看到我們組件對應(yīng)的podspec了。
在本地的repo里也能發(fā)現(xiàn)我們的spec
現(xiàn)在執(zhí)行
pod search QFCommon //應(yīng)該就可以搜索到我們的組件了,
如果搜索不到,可以刪除索引,試試。
m ~/Library/Caches/CocoaPods/search_index.json
走到這里我們算是把私有庫制作完成了,因?yàn)槭撬接袔欤谑褂玫臅r(shí)候,需要在對應(yīng)的podfile
添加上私有庫對應(yīng)的,podspec的路徑
在制作的過程中遇到的坑
1,
如果你的podspec
文件里包含中文字符,那么在pod lib lint
驗(yàn)證的時(shí)候有可能會報(bào)utf8
編碼錯(cuò)誤,所以盡量不要在podspec
里包含中文。
2,在設(shè)置子組件時(shí),如果依賴于其他庫,需要設(shè)置;
其中如果A文件夾下依賴于另一個(gè)B文件夾的內(nèi)容也需要設(shè)置相應(yīng)的 依賴路徑,不然在
pod repo push
的時(shí)候,有可能會報(bào)
xxxx.h' file not found
3, 如果私有庫里包含Xib
文件 那么在加載xib
是需要根據(jù)bundle
加載。
NSString *className = NSStringFromClass([self class]);
NSBundle *bundle = [NSBundle bundleForClass:self];
NSString *bundleName = bundle.infoDictionary[@"CFBundleName"];
NSString *nibName = [NSString stringWithFormat:@"%@.bundle/%@", bundleName, className];
return [bundle loadNibNamed:nibName owner:nil options:nil].lastObject;
并且 需要在podspec 里描述相應(yīng)的路徑。
s.resource_bundles = {
'QFCommon' => ['QFCommon/Classes/Tools/**/*.xib']
}
另外在使用私有庫的時(shí)候,因?yàn)榘速Y源文件,那么就需要將podfile
里面的 use_frameworks!
打開,不然會找不到資源。
Could not load NIB in bundle:
如果包含圖片,需要將圖片放在,私有庫對應(yīng)的Assets
里面。
并且將路徑描述在,
s.resource_bundles
的數(shù)組里 (多個(gè)路徑,可以相應(yīng)的依次添加)
s.resource_bundles = {
'QFCommon' => ['QFCommon/Classes/Tools/**/*.xib', xxx/xxx/xxx]
}
5, 如果確定已經(jīng)打上tag,并且在遠(yuǎn)程倉庫上也能找到tag,但是在推送podspec
到遠(yuǎn)程的時(shí)候報(bào):
Remote branch 0.0.1 not found in upstream origin
查看podspec
里s.source
的地址是否和遠(yuǎn)程倉庫的地址一致。