Cocoapods私有倉庫全部流程(不止從0到1)

一. cocoapods內(nèi)在原理

還記得我們用cocoapods創(chuàng)建的podfile文件第一行有這一行

source 'https://github.com/CocoaPods/Specs.git'

然后我們想用某個(gè)第三方的時(shí)候是這樣寫的

pod 'AFNetworking', '~> 0.1.0'

那第一行是個(gè)什么地址呢?
請進(jìn)入你如下路徑

~/.cocoapods/repo

是否有看到一個(gè)master文件夾,以及cocoapods1.8.0之后會(huì)多一個(gè)trunk文件夾,這個(gè)是cocoapods把specs repo的源給切換成cdn了。
終端輸入

pod repo

輸出如下

master
- Type: git (master)
- URL:  https://github.com/CocoaPods/Specs.git
- Path: /Users/kang/.cocoapods/repos/master

trunk
- Type: CDN
- URL:  https://cdn.cocoapods.org/
- Path: /Users/kang/.cocoapods/repos/trunk

可以看到master是git上的一個(gè)倉庫,而trunk是cdn,cdn這個(gè)暫時(shí)不過多說明,目的就是為了加快我們pod install/update的速度。而master對應(yīng)的url就是github上的一個(gè)倉庫,這個(gè)倉庫存放的就是個(gè)人發(fā)的自己寫的第三方庫(如AFNetworking等我們經(jīng)常用的三方)的podspec文件,此文件應(yīng)該不陌生,就是個(gè)人上傳時(shí)候包含代碼各種信息,代碼存儲(chǔ)地址的那個(gè)文件,如下

Pod::Spec.new do |s|
  s.name             = 'XXXKit'
  s.version          = '0.3.0'
  s.summary          = 'A short description of XXXKit.'
  s.description      = <<-DESC
TODO: Add long description of the pod here.
                       DESC

  s.homepage         = 'https://gitee.com/kzq5/XXXKit.git'
  s.license          = { :type => 'MIT', :file => 'LICENSE' }
  s.author           = { 'kang' => 'xxx@qq.com' }
  s.source           = { :git => 'https://gitee.com/xxx/XXXKit.git', :tag => s.version.to_s }
  s.ios.deployment_target = '8.0'
  s.resource_bundles = {
    'XXXKit' => ['XXXKit/Assets/*.png','XXXKit/Assets/*.caf']
  }
  s.subspec 'Category' do |c|
    c.source_files = 'XXXKit/Classes/Category/**/*'
  end
  s.subspec 'Utils' do |u|
    u.source_files = 'XXXKit/Classes/Utils/**/*'
  end
  #s.source_files = 'XXXKit/Classes/**/*'
  # s.public_header_files = 'Pod/Classes/**/*.h'
  # s.frameworks = 'UIKit', 'MapKit'
  # s.dependency 'AFNetworking', '~> 2.3'
end

到此,來說說cocoapods的原理吧:
定義幾個(gè)別名先。

Cocoapods source 對應(yīng) https://github.com/CocoaPods/Specs.git
AFNetworking source 對應(yīng) https://github.com/AFNetworking/AFNetworking

Cocoapods source 這個(gè)地址是個(gè)公共倉庫,里邊存儲(chǔ)各個(gè)第三方的podspec文件,這個(gè)podspec文件中記錄有各自第三方庫的倉庫地址;
比如我們用的AFNetworking,他在github上倉庫地址是這個(gè)AFNetworking source,其中包含對應(yīng)的podspec文件,這個(gè)文件中有存儲(chǔ)AFNetworking source這個(gè)地址,并且Cocoapods source 中有存儲(chǔ)有這個(gè)文件,那么當(dāng)我們在使用的時(shí)候直接用
pod 'AFNetworking', '~> 0.1.0'的時(shí)候,cocoapods會(huì)去Cocoapods source 中查找AFNetworking對應(yīng)的podspec文件,找到后從中取出AFNetworking source這個(gè)地址,然后里邊就是我們要的第三方庫的源碼了,至于后續(xù)怎么處理那就是后話了?,F(xiàn)在只是在討論cocoapods的原理,即怎么通過一個(gè)第三方的名字去找對應(yīng)的源碼。
看如下圖的展示


Cocoapods source中存儲(chǔ)的afnetworking庫的podspec文件路徑
Cocoapods source中存儲(chǔ)的afnetworking庫的podspec文件內(nèi)容

二. cocoapods私有倉庫

剛才說的都是cocoapods上的公共倉庫,大家知道名字就能用,那如何搞自己的私有倉庫呢?就是還是以pod的方式使用,但是只有自己能用,別人用不了,除非你給授權(quán)。
其實(shí)吧,私有倉庫和公共倉庫操作是一樣的,只是創(chuàng)建倉庫的時(shí)候你選擇的是私有還是公共而已。

2.1 先來一步一步創(chuàng)建自己的私有倉庫

首先在代碼托管平臺(tái)創(chuàng)建一個(gè)私有倉庫,我是選擇碼云,如圖

圖片.png

創(chuàng)建好之后會(huì)生成一個(gè)倉庫地址,類似這樣的https://gitee.com/xxx/MyProjectBase,記著這個(gè)地址,后邊會(huì)用到。

2.2 本地快速創(chuàng)建模板測試工程

快速創(chuàng)建模板測試工程,如在/Users/用戶/Desktop/路徑下創(chuàng)建CocoaPodRemoteLib目錄,然后終端輸入

cd /Users/Funky/Desktop/CocoaPodRemoteLib
pod lib create MyProjectBase

此時(shí)會(huì)有一些具體的選項(xiàng),選擇一下即可,如圖


圖片.png

填寫以上信息后Xcode會(huì)自動(dòng)打開測試工程,在測試模板工程文件夾下,我們可以看到如下:


圖片.png

假如我們要?jiǎng)?chuàng)建的第三方是個(gè)Category,則用Category去替換Replace.m文件,在回到Example路徑下,重新執(zhí)行pod install操作,即在終端輸入

cd /Users/用戶/Desktop/CocoaPodRemoteLib/MyProjectBase/Example
pod install

此時(shí)打開模板測試工程,我們可以看到Pods > Development Pods > MyProjectBase > MyProjectBase > Classes > Category > (.h .m)
我們可以在模板測試工程中進(jìn)行修改和操作!

2.3 將上面的模板測試工程,提交到第四步創(chuàng)建的遠(yuǎn)程代碼倉庫

在終端輸入如下命令

cd /Users/用戶/Desktop/CocoaPodRemoteLib/MyProjectBase
git status
git add .
git commit -m'基礎(chǔ)組件測試工程'

編輯MyProjectBase 模版工程的MyProjectBase.podspec文件


盜圖,文末會(huì)有參考地址

編輯完之后在終端輸入此命令(驗(yàn)證上一步編輯的 MyProjectBase.podspec文件)

pod lib lint

如果有ERROR,則需要去一個(gè)個(gè)修改完成,例如某個(gè)Category的.m文件沒有正確的引入依賴庫等都會(huì)造成ERROR,解決好所有的ERROR后,驗(yàn)證結(jié)果如下:


圖片.png

git status
git add .
git commit -m '編輯spec文件'
這是一個(gè)警告,目前也并沒有找到合適的解決辦法,我們添加 --allow-warnings進(jìn)行忽略
pod lib lint --allow-warnings

此時(shí) MyProjectBase passed validation. 則說明驗(yàn)證通過

將本地庫與遠(yuǎn)程代碼倉庫進(jìn)行關(guān)聯(lián)

git remote add origin (2.1中生成的碼云倉庫地址)
git push origin master (提交到遠(yuǎn)程倉庫)
git tag '0.1.0' (要與MyProjectBase.podspec文件中的tag值保持一致)
git push --tags(將tag提交到遠(yuǎn)程)
pod spec lint --allow-warnings(驗(yàn)證遠(yuǎn)程是否正確)

提示MyProjectBase.podspec passed validation表明驗(yàn)證通過。

此時(shí)私有庫已經(jīng)可以通過pod來管理使用了,只是不能用通常的pod引入方式
現(xiàn)在我們想用此私有倉庫在podfile中這樣寫

pod 'MyProjectBase', :git =>'https://gitee.com/xxx/MyProjectBase.git'

然后終端執(zhí)行pod install即可。
但是有個(gè)問題,為什么不能直接用名字,不加后邊的git地址呢?
其實(shí)想象一下最開始cocoapods的原理,pod通過名字去pod倉庫中找到對應(yīng)名字的podspec文件,然后在podspec文件中找到代碼。
而我們此時(shí)的私有倉庫如果不加后邊的git地址的話,根本沒辦法找到對應(yīng)代碼。那么如果想用正常的方式用這個(gè)私有倉庫就需要把私有庫的podspec放一個(gè)類似官方master文件夾的地方。下邊就開始著手做這個(gè)工作。

三. 創(chuàng)建私有倉庫的索引倉庫

因?yàn)楣俜骄陀幸粋€(gè)索引倉庫,然后通過索引倉庫來管理第三方庫,那么我們也可以仿照官方的做法,自己見一個(gè)私有的索引倉庫

3.1 新建私有索引倉庫

**在碼云上創(chuàng)建一個(gè)自己的遠(yuǎn)程私有索引庫,用來存放私有框架的詳細(xì)描述信息,即podspec文件

圖片.png

創(chuàng)建好后也會(huì)生成一個(gè)git倉庫的地址https://,然后在終端輸入此命令添加本地私有索引庫并管理對應(yīng)的遠(yuǎn)程私有庫地址

pod repo add MyProjectSpec https://gitee.com/xxx/MyProjectSpec.git

再次查看本地已存在的索引庫 $ pod repo


圖片.png

此時(shí)我們的私有索引庫已將創(chuàng)建完成,類似官方的master目錄,那么接下來就是把我們之前創(chuàng)建的私有庫的podspec文件上傳到我們的私有索引庫中即可。

3.2 上傳私有庫podspec文件到私有索引庫

進(jìn)入我們的私有庫目錄,然后終端輸入

pod repo push MyProjectSpec MyProjectBase.podspec

圖片.png

表示提交成功,此時(shí)遠(yuǎn)程私有庫到此就已結(jié)束

注意:提交后,依然會(huì)驗(yàn)證 podspec文件,驗(yàn)證通過后 會(huì)自動(dòng)上傳到在遠(yuǎn)程spec索引庫,不信的話你可以看看在第二步創(chuàng)建的Spec遠(yuǎn)程私有索引庫,是不是多了一個(gè)MyProjectBase/ 0.1.0文件.

到此為止,我們自己的私有庫已經(jīng)全部搞定,下邊我們就可以正常的使用了,如下

pod 'MyProjectBase'

但是這樣還不行,因?yàn)閜od默認(rèn)會(huì)去官方的索引庫,即master中找這個(gè)庫,但是我們這個(gè)是私有庫,怎么可能在官方的索引庫中,此時(shí)就要像文章最開始那樣,把我們自己私有的索引庫地址給加上,即在podfile開頭,加上

source 'https://gitee.com/xxx/MyProjectSpec.git'

pod install即可在工程中的pod目錄中看到我們自己的私有庫了。

四. 私有庫修改后的操作

如下圖:

image

在本地的基礎(chǔ)組件的Classes路徑下 又新增了兩個(gè)文件夾(Base,Tool)

$ cd /Users/Funky/Desktop/CocoaPodRemoteLib/MyProjectBase

編輯MyProjectBase 模版工程的MyProjectBase.podspec文件

image
$ git status
$ git add .
$ git commit -m'新增Base,Tool文件內(nèi)容'
$ git push origin master (提交到遠(yuǎn)程)
$ git tag '0.2.0'
$ git push --tags
$ pod repo push MyProjectSpec MyProjectBase.podspec (如果沒有私有庫索引倉庫,不需要在push到索引庫)
$ cd /Users/Funky/Desktop/CocoaPodRemoteLib/MyMainProject

修改Podfile文件

image

$ pod install即可

五. 私有庫分拆子庫

在基礎(chǔ)組件MyProjectBase內(nèi)部生成子庫

問題描述:當(dāng)我們執(zhí)行完第九步后,我們發(fā)現(xiàn)主工程的Pods中并沒有按文件夾(Base,Category,Tool)進(jìn)行不同類的劃分,同時(shí)當(dāng)我們僅僅想引入一個(gè)Category庫時(shí),連同Base,Tool也引入進(jìn)項(xiàng)目中,這就太難受了!

參照AFNetworking

image

修改MyProjectBase.podspec文件

image

$ cd /Users/Funky/Desktop/CocoaPodRemoteLib/MyProjectBase

$ git status

$ git add .

$ git commit -m'生成子庫文件夾'

$ git push origin master (提交到遠(yuǎn)程)

$ git tag '0.2.0'

$ git push --tags

$ pod repo push MyProjectSpec MyProjectBase.podspec

$ cd /Users/Funky/Desktop/CocoaPodRemoteLib/MyMainProject

修改Podfile文件

image

$ pod install

就現(xiàn)在 快打開主工程看一看吧!

說個(gè)有意思的東西

先看下cocoapods的索引庫master的目錄結(jié)構(gòu)


圖片.png

這個(gè)目錄結(jié)構(gòu)有看的懂得嗎?什么鬼全是單個(gè)數(shù)字或者字母,其實(shí)有其巧妙之處的,看前兩個(gè)三方庫的md5加密后的字符串


AlamofireDomain
CTHandyCategories

有發(fā)現(xiàn)什么嗎?他們加密后字符串開頭都是456,而他們在master中目錄是4文件夾-〉5文件夾-〉6文件夾。
所以cocoapods找一個(gè)三方庫的podspec文件的時(shí)候其實(shí)是先把三方的名字md5加密,然后就直接那前三位找到對應(yīng)目錄就是這個(gè)三方庫對應(yīng)的podspec文件的地址了,效率非常的高,也很巧妙。

參考:
我這篇大部分是參考這篇文章,然后在次序上做了調(diào)整,但也有很多自己的思考,畢竟自己實(shí)操過的
轉(zhuǎn)載的上述文章,怕別人刪了以后看不到??
Cocopods組件化之podspec文件解析
podspecs文件說明
官方podspec文檔
官方podfile文檔
Cocoapods驗(yàn)證podspec報(bào)錯(cuò)總結(jié)
AFNetworking的podspec文件,看看牛逼的庫怎么寫的??

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容