
根據(jù)pod的使用原理,當(dāng)使用pod install 安裝庫(kù)時(shí),會(huì)在索引倉(cāng)庫(kù)中搜對(duì)應(yīng)的庫(kù),搜到后,根據(jù)索引倉(cāng)中的spec文件中的信息,去對(duì)應(yīng)的git倉(cāng)庫(kù)中拉取相應(yīng)的代碼?;诖?,我們添加一個(gè)私有索引倉(cāng)即可。官方文檔:構(gòu)建私有pod
本文記錄創(chuàng)建私有倉(cāng)的方法,以及提交一個(gè)測(cè)試項(xiàng)目到私有倉(cāng),再通過(guò)pod的方式加載測(cè)試項(xiàng)目的步驟。
一、構(gòu)建遠(yuǎn)程私有庫(kù)
我們需要準(zhǔn)備兩個(gè)空的遠(yuǎn)程倉(cāng)庫(kù),一個(gè)作為私有索引庫(kù)作為全部spec的存放倉(cāng)庫(kù)即索引庫(kù),另一個(gè)為模擬要發(fā)布的私有組件倉(cāng)庫(kù)。
第一步:創(chuàng)建私有組件庫(kù)項(xiàng)目
這一步是通過(guò)pod 自帶的cli命令創(chuàng)建項(xiàng)目,該項(xiàng)目中會(huì)將需要發(fā)布的代碼以本地pod的方式引入,并同時(shí)創(chuàng)建測(cè)試項(xiàng)目以及對(duì)應(yīng)的配置文件,為之后的發(fā)布做好準(zhǔn)備。
將空倉(cāng)庫(kù)私有組件庫(kù)clone到本地,cd進(jìn)入目錄后輸入pod lib create XXXX創(chuàng)建新項(xiàng)目,XXXX 是項(xiàng)目名稱,一般都會(huì)以組件名稱命名。我們這里使用BaseMoudle作為組件名稱,輸入pod lib create BaseMoudle,然后填寫(xiě)相關(guān)信息后會(huì)自動(dòng)生成項(xiàng)目(這里單詞寫(xiě)錯(cuò)了,應(yīng)該是Module,忽略這個(gè)小問(wèn)題):
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 ]
> Yes
Which testing frameworks will you use? [ Specta / Kiwi / None ]
> None
Would you like to do view based testing? [ Yes / No ]
> no
What is your class prefix?
> Test
完成后項(xiàng)目會(huì)自動(dòng)打開(kāi),項(xiàng)目結(jié)構(gòu)如下:

目錄結(jié)構(gòu)如下:

最左邊的BaseMoudle是git倉(cāng)庫(kù)clone的目錄,中間的BaseMoudle是pod創(chuàng)建的項(xiàng)目所在的文件夾,右邊的BaseMoudle才是真正放庫(kù)代碼的地方。
此時(shí),發(fā)現(xiàn)git不能提交,并沒(méi)有識(shí)別到這個(gè)新創(chuàng)建的項(xiàng)目,這是因?yàn)樵撐募A下也有.git文件,這是pod的項(xiàng)目下載下來(lái)的,刪掉即可(如果沒(méi)有可以按鍵command + shift + . 顯示隱藏文件)。
同時(shí),為了方便期間,我們把中間這個(gè)多余的BaseMoudle層級(jí)也刪除掉。
最終,目錄結(jié)構(gòu)如下:

第二步:修改.podspec文件
.podspec 文件是存放在索引庫(kù)中的,pod會(huì)根據(jù)該文件中的配置去下載對(duì)應(yīng)的文件。該文件最終會(huì)上傳到索引庫(kù)中。
打開(kāi)工程后,找到BaseMoudle..podspec文件,該文件是默認(rèn)生成的,必須修改的字段如下:
s.summary = '基礎(chǔ)庫(kù)'
s.description = <<-DESC
這里填寫(xiě)比summary更多的內(nèi)容做為描述
DESC
s.homepage = '填寫(xiě)庫(kù)的地址,比如https://gitee.com/xxxxx/xxxxx'
s.source = { :git => '填寫(xiě)庫(kù)的代碼地址,比如https://xxx.git', :tag => s.version.to_s }
這里,我們添加一些測(cè)試代碼,需要將組件的代碼放到這個(gè)文件夾下(ReplaceMe文件可以刪除)。

正確的代碼添加的方式是將代碼放在和BaseMoudle.podspec同層級(jí)的BaseMoudle ->Classes文件夾下,然后在Example文件夾下執(zhí)行pod install加載代碼到項(xiàng)目中(即這是一個(gè)本地pod引入代碼方式)。
提交代碼后,需要給該次提交打一個(gè)標(biāo)簽,標(biāo)簽必須和.podspec文件中version字段一致。默認(rèn)這里是0.1.0。
在BaseMoudle.podspec同級(jí)目錄中,可以使用指令pod spec lint 對(duì)文件進(jìn)行驗(yàn)證(會(huì)檢測(cè)填寫(xiě)的遠(yuǎn)程地址的是否可用,以及一些其他的合法性檢測(cè)。)
注意:
- s.description 必須比 s.summary 更長(zhǎng),這里的格式也不能修改,寫(xiě)在DESC兩個(gè)關(guān)鍵字中間一行
- s.source中,
:git =>字段,這里如果寫(xiě)git@xxx.git這種地址,則需要使用pod ''xxx" 的用戶是配置了SSH認(rèn)證方式,否則會(huì)有權(quán)限錯(cuò)誤。所以通常這里寫(xiě)https://xxx.git這樣的方式確??梢哉@〈a。- s.source中,
:tag =>字段,理論上tag是一個(gè)字符串(git中關(guān)于tag官方文檔描述),但仍需遵循一些規(guī)則。
tag中關(guān)于名稱的描述
具體規(guī)則詳見(jiàn)文檔。通常,我們以一個(gè)類似0.1.0這樣的方式設(shè)置tag。這是因?yàn)?,在pod管理中,可以使用一些方式限定加載的版本,比如~>之類的,只有這樣的版本號(hào)才能正確解析。否則就需要指定版本號(hào)。
第三步:添加私有索引庫(kù)搜索地址
在執(zhí)行pod install 的時(shí)候,會(huì)在當(dāng)前的pod索引庫(kù)中查找?guī)欤ㄊ褂?code>pod repo指令可以查看當(dāng)前所有的索引庫(kù)),為了能查詢私有索引倉(cāng),我們需要添加私有倉(cāng)地址到搜索庫(kù)中。
使用pod repo add XxxName XxxPath( 其中XxxName是自定的repo名稱,比如PrivateRepo,XxxPath為該索引庫(kù)的地址,比如 https://xxx.git)指令添加一個(gè)私有的全局pod 索引庫(kù)。
添加完成后,可以使用pod repo查看列表是否添加成功。
// 輸入pod repo 后查看索引庫(kù)信息
cocoapods
- Type: git (remotes/origin/master)
- URL: https://github.com/CocoaPods/Specs.git
- Path: /Users/x/.cocoapods/repos/cocoapods
Private
- Type: git (master)
- URL: https://xxx.git
- Path: /Users/x/.cocoapods/repos/Private
trunk
- Type: CDN
- URL: https://cdn.cocoapods.org/
- Path: /Users/x/.cocoapods/repos/trunk
第四步:將私有庫(kù)的podspec文件推送到私有索引倉(cāng)庫(kù)中
在BaseMoudle.podspec文件的所在的目錄下執(zhí)行pod repo push PrivateRepo BaseMoudle.podspec,表示給PrivateRepo索引庫(kù)中推送podspec(這里是pod的推送命令,并不是git的推送命令,該指令會(huì)檢查.podspec文件的合法性):
Validating spec
-> BaseMoudle (0.1.0)
- WARN | source: Git SSH URLs will NOT work for people behind firewalls configured to only allow HTTP, therefore HTTPS is preferred.
- WARN | url: The URL (https://xxx.git) is not reachable.
- NOTE | xcodebuild: note: Using new build system
- NOTE | xcodebuild: note: Using codesigning identity override: -
- NOTE | xcodebuild: note: Build preparation complete
- NOTE | [iOS] xcodebuild: note: Planning
- NOTE | [iOS] xcodebuild: note: Building targets in dependency order
- NOTE | [iOS] xcodebuild: warning: Skipping code signing because the target does not have an Info.plist file and one is not being generated automatically. (in target 'App' from project 'App')
Updating the `PrivateRepo' repo
Adding the spec to the `PrivateRepo' repo
- [Add] BaseMoudle (0.1.0)
Pushing the `PrivateRepo' repo
可以看到,這里會(huì)自動(dòng)執(zhí)行Pushing thePrivateRepo' repo`指令,即對(duì)遠(yuǎn)程索引倉(cāng)庫(kù)自動(dòng)進(jìn)行g(shù)it的push操作,將其更新到遠(yuǎn)程倉(cāng)庫(kù)。
注意,這里可以直接不寫(xiě)
BaseMoudle.podspec參數(shù),即pod repo push PrivateRepo,會(huì)自動(dòng)查找當(dāng)前目錄下的.podspec文件。
第五步:安裝遠(yuǎn)程庫(kù)
默認(rèn)pod 搜索的只是默認(rèn)的索引庫(kù),我們需要在Podfile文件中添加更多的索引庫(kù)地址。
創(chuàng)建一個(gè)新項(xiàng)目,初始化pod后,在Podfile文件最上方填寫(xiě)source信息(可通過(guò)pod repo指令查看),表示需要搜索的索引庫(kù)地址,然后引入庫(kù)文件pod 'BaseMoudle':
# Uncomment the next line to define a global platform for your project
# platform :ios, '9.0'
source 'https://github.com/CocoaPods/Specs.git'
source 'https://xxx.git'
target 'test' do
# Comment the next line if you don't want to use dynamic frameworks
use_frameworks!
# Pods for test
pod 'BaseMoudle'
end
執(zhí)行pod install 即可
第六步:升級(jí)遠(yuǎn)程庫(kù)(可選)
當(dāng)需要對(duì)庫(kù)進(jìn)行升級(jí)時(shí),需要修改.podspec文件,同時(shí),對(duì)代碼重新打tag,和第二步一致。然后執(zhí)行第四步,重新推送到本地repo。
在項(xiàng)目中,需要執(zhí)行pod update --no-repo-update,更新文件。這里使用pod install 是不行的,因?yàn)樵?code>Podfile.lock文件中已經(jīng)“鎖定”了版本號(hào),只有update指令才可以去更新這里的庫(kù),而--no-repo-update表示更新repo中的文件(本地索引庫(kù)),私有的索引庫(kù)已經(jīng)更新了(第六步中重新推送到本地repo),使用該命令可以避免更新官方的索引庫(kù)(如果沒(méi)有顯式的指定其他庫(kù)的版本號(hào),不加--no-repo-update會(huì)導(dǎo)致其他的庫(kù)更新到最新版本從而引起一些問(wèn)題)。
二、常見(jiàn)問(wèn)題處理:
1.[iOS] file patterns: The `source_files` pattern did not match any file. 或者 [iOS] file patterns: The `resource_bundles` pattern for `xxx` did not match any file.
出現(xiàn)這中錯(cuò)誤有幾種可能:
字段設(shè)置錯(cuò)誤
字段修改為第二步中的,特別是s.description,要在<<-DESC和DESC寫(xiě)注釋,不能刪掉文件夾路徑錯(cuò)誤
在第一步中刪掉多余的BaseMoudle層級(jí)才能正確匹配s.source_files = 'BaseMoudle/Classes/**/*'字段,如果沒(méi)有刪除,則這里應(yīng)該為s.source_files = 'BaseMoudle/BaseMoudle/Classes/**/*'版本號(hào)沒(méi)有修改
更新版本后沒(méi)有修改版本號(hào)s.version字段,即重復(fù)提交了相同的版本號(hào)。修改版本號(hào)后重新提交即可。
2.Could not find remote branch 0.1.0 to clone.
這個(gè)錯(cuò)誤是由于沒(méi)有打標(biāo)簽,會(huì)檢測(cè)到找不到該標(biāo)簽。如果沒(méi)有打標(biāo)簽這個(gè)錯(cuò)誤不一定會(huì)有,gitee上不打也可驗(yàn)證通過(guò),gitlab就會(huì)有這樣的錯(cuò)誤,可能和倉(cāng)庫(kù)有關(guān)系。但是在具體安裝的時(shí)候(pod install),如果沒(méi)有標(biāo)簽也會(huì)報(bào)錯(cuò)找不到該標(biāo)簽。
3.Specs satisfying the xxxx dependency were found, but they required a higher minimum deployment target.
這個(gè)是安裝的庫(kù)的版本比podfile中的版本高,在.podspec文件中s.ios.deployment_target字段配置版本信息。
4.Could not read from remote repository
報(bào)錯(cuò)信息如下:
[!] Error installing xxxxxxx
[!] /usr/bin/git clone git@gitlab.xxxxx.xxxxx/xxxxx/xxxxxx.git /var/folders/f8/jkfbygnx2hvfx6s4k78vw51h0000gn/T/d20220406-63219-53c6s0 --template= --single-branch --depth 1 --branch 0.1.0
Cloning into '/var/folders/f8/jkfbygnx2hvfx6s4k78vw51h0000gn/T/d20220406-63219-53c6s0'...
ssh: Could not resolve hostname gitlab.autel.com: nodename nor servname provided, or not known
fatal: Could not read from remote repository.
Please make sure you have the correct access rights
and the repository exists.
該問(wèn)題并非git配置問(wèn)題,是文件夾寫(xiě)入權(quán)限問(wèn)題。執(zhí)行一次sudo pod install輸入電腦密碼,再執(zhí)行一次pod install即可正常安裝。
5.庫(kù)中有文件夾,引入后文件夾丟失
當(dāng)只有一個(gè)文件夾或者文件夾中是空的時(shí)候,pod在引入的時(shí)候會(huì)對(duì)其進(jìn)行過(guò)濾。這是一個(gè)正常現(xiàn)象
6. 只有WARN和NOTE仍然不能提交成功,提示[!] The `xxxxx.podspec` specification does not validate.
在后面添加--allow-warnings參數(shù)即可。參考文章
7. 提交成功后別人使用pod install仍然安裝的是舊版本
這個(gè)問(wèn)題是pod的索引緩存問(wèn)題,通過(guò)pod repo update XXX更新本地索引庫(kù)即可。在本機(jī)上通過(guò)第四步已經(jīng)推送到本地索引庫(kù)上則無(wú)需此操作。
注意:這里自己雖然本地上的索引庫(kù)已經(jīng)更新,但是安裝仍然是舊版,這是因?yàn)?code>Podfile.lock這個(gè)文件中會(huì)鎖定版本信息。我們可以先注釋引入的pod庫(kù),然后執(zhí)行pod install將其移除,再重新引入pod庫(kù),執(zhí)行pod install即可安裝到最新版本了。
8. 報(bào)錯(cuò)- ERROR | [iOS] unknown: Encountered an unknown error (incompatible character encodings: UTF-8 and ASCII-8BIT) during validation.
檢查s.source中配置的路徑是否正確,這種錯(cuò)誤往往是驗(yàn)證的url中存在異常字符
