
關(guān)于組件庫文件夾分層可以參考
組件庫(私有庫)維護---文件分層和文件夾一起有層次上傳
使用Cocoapods創(chuàng)建/管理私有庫(高級用法)
在上一篇文章CocoaPods,創(chuàng)建屬于自己的公開庫 中我們講了如何將自己的框架發(fā)布到CocoaPods中供別人來使用。在這一篇文章我將來介紹下如何利用CocoaPods來打造屬于自己的遠程私有庫。
背景
隨著公司業(yè)務(wù)的發(fā)展以及產(chǎn)品線的增加,我們需要將APP拆分為若干個基礎(chǔ)組件、功能組件和業(yè)務(wù)組件,以便跨APP使用,并且為了方便管理和維護,對于這些組件我們也想利用CocoaPods來統(tǒng)一管理,但是呢又不想開源讓別人使用,只是想讓自己內(nèi)部的團隊去使用,這種情況該如何操作呢?下面我們就一步步的帶領(lǐng)大家去創(chuàng)建一個屬于自己的遠程私有倉庫。
一在代碼托管平臺創(chuàng)建私有庫
在代碼托管平臺創(chuàng)建私有倉庫,因為GitHub上私有倉庫需要收費,這里以Coding.net為例,如下圖:

二 創(chuàng)建PodSpec文件
據(jù)我所知創(chuàng)建PodSpec文件可以通過兩種方式,第一種通過 pod spec create xxx命令來創(chuàng)建,第二種就是通過 pod lib create xxx命令來創(chuàng)建,相比較之下我更喜歡第二種方式。因為通過第二種方案我們可以選擇生成Example工程和測試框架,方便調(diào)試以及幫助他人學(xué)習(xí)使用,更加的方便。
在終端中 cd 到一個空的目錄下,運行如下命令:
pod lib create privateLib
CocoaPods會讓我們回答幾個問題,如下圖所示:

把組件相關(guān)的類放到 privateLib/Classes 目錄中,這是因為 Example 工程生成的 Podfile 文件中指定了這個目錄是源文件地址,我們將一個UIView的分類放到該目錄下,如下:

然后在終端中 cd 到 Example 目錄下并運行 pod install命令,將我們的宿主工程也就是Example與我們拖入的組件建立依賴關(guān)系,這樣我們就可以正常的使用我們的Example工程了。
三 發(fā)布組件到代碼托管平臺
在代碼托管平臺上建立一個私有的倉庫
git add .
git commit -m "項目初始化"
git remote add origin https://git.coding.net/Guanzp/privateLib.git
緊接著給我們的組件打上標(biāo)簽,其實也就是版本
git tag -a "0.1.0" -m "Version 0.1.0"
git push --tags
注:
// 刪除本地tag
git tag -d <tagname>
// 刪除遠程tag
git push origin --delete <tagname>
四 編輯 podspec 文件
接下來我們要編輯 podspec 文件,因為在上一篇文章中我們已經(jīng)詳細的介紹過該文件這里就不在贅述。然后通過 pod lib lint測試 podspec 文件是否可用
五 創(chuàng)建私有Spec庫
在 代碼托管平臺上另外建一個名字為 spec 的倉庫,作為我們私有的 podspec 專用倉庫,用于存儲spec文件, 而不是我們的項目, 然后在本地添加一個新的源
pod repo add privateSpec https://git.coding.net/Guanzp/privateSpec.git
然后我們就會發(fā)現(xiàn)在本地多了一個名稱為privateSpec的索引庫

緊接著將剛才我們編輯好的podspec文件push到本地spec索引庫中,同時同步到遠程spec庫中。
pod repo push privateSpec privateLib.podspec
這樣遠程倉庫和本地索引庫中就都有了


五 使用遠程私有庫
使用方式和其他的開源庫一樣,但不同的是,需要在頭部增加
source 'https://github.com/CocoaPods/Specs.git'#github 官方倉庫地址
source 'https://git.coding.net/xxx/privateSpec.git'#自己的遠程私有庫地址
use_frameworks!
target 'privateLibTest' do
pod 'privateLib'
end
遇到的問題
-
pod lib lint驗證成功了,但是在接下來的pod repo push報錯而且報的是就是podspec無法通過驗證,解決方法,重新提交一個tag并push。在執(zhí)行pod repo push,驗證通過。
后記
- 組件依賴。有時候我們開發(fā)的組件有可能會依賴其它三方的組件,比如我們的組件對
AFNetWorking和SDWebImage有依賴:這個時候我們只需要在podspec文件中添加下面兩個依賴即可。
s.dependency 'AFNetworking'
s.dependency 'SDWebImage'
- 資源加載問題。當(dāng)組件中使用到圖片等資源文件的時候,可以將圖片放到
Assets文件夾中,如下圖:
[圖片上傳失敗...(image-74892f-1516092123165)]
同時,我們需要對podspec文件進行修改,指定Bundle資源文件路徑:
s.source_files = 'XMGFMMain/Classes/**/*'
s.resource_bundles = {
'XMGFMMain' => ['XMGFMMain/Assets/*']
}
因為圖片是存放在組件中,所以需要在當(dāng)前類所在的Bundle中去查找圖片資源,而不是在MainBundle中。比如下圖:
[圖片上傳失敗...(image-38f09f-1516092123165)]
NSBundle *currentBundle = [NSBundle bundleForClass:[self class]];
NSString *imagePath = [currentBundle pathForResource:@"tabbar_bg@2x.png" ofType:nil inDirectory:@"XMGFMMain.bundle"];
UIImage *image = [UIImage imageWithContentsOfFile:imagePath];
self.backgroundImage = image;
同理,在組件中加載xib文件
NSBundle *currenBundle = [NSBundle bundleForClass:self];
XMGMiddleView *middleView = [[currenBundle loadNibNamed:@"XMGMiddleView" owner:nil options:nil] firstObject];
- 統(tǒng)一披露API。組件內(nèi)部提供的服務(wù)很多, 如果他人使用, 無法確定有哪些API,如何解決?可以通過統(tǒng)一披露API來解決這個問題。在API中我們需要考慮:需要提供哪些服務(wù)給外界;外界需要給你提供哪些服務(wù)等;
- 當(dāng)大家在進行
pod search AFNetWorking時候,我們會發(fā)現(xiàn)它下面有很多Subspaces,其實很容易理解,有時候我們只想用AFNetWorking中的Reachability,而又不想將AFNetWorking整個框架都導(dǎo)入進來。那么我們可不可以模仿它這么做呢?
-> AFNetworking (3.1.0)
A delightful iOS and OS X networking framework.
pod 'AFNetworking', '~> 3.1.0'
- Homepage: https://github.com/AFNetworking/AFNetworking
- Source: https://github.com/AFNetworking/AFNetworking.git
- Versions: 3.1.0, 3.0.4, 3.0.3, 3.0.2, 3.0.1, 3.0.0, 3.0.0-beta.3,
3.0.0-beta.2, 3.0.0-beta.1, 2.6.3, 2.6.2, 2.6.1, 2.6.0, 2.5.4, 2.5.3, 2.5.2,
2.5.1, 2.5.0, 2.4.1, 2.4.0, 2.3.1, 2.3.0, 2.2.4, 2.2.3, 2.2.2, 2.2.1, 2.2.0,
2.1.0, 2.0.3, 2.0.2, 2.0.1, 2.0.0, 2.0.0-RC3, 2.0.0-RC2, 2.0.0-RC1, 1.3.4,
1.3.3, 1.3.2, 1.3.1, 1.3.0, 1.2.1, 1.2.0, 1.1.0, 1.0.1, 1.0, 1.0RC3, 1.0RC2,
1.0RC1, 0.10.1, 0.10.0, 0.9.2, 0.9.1, 0.9.0, 0.7.0, 0.5.1 [master repo]
- Subspecs:
- AFNetworking/Serialization (3.1.0)
- AFNetworking/Security (3.1.0)
- AFNetworking/Reachability (3.1.0)
- AFNetworking/NSURLSession (3.1.0)
- AFNetworking/UIKit (3.1.0)
其實很簡單,我們只需要在podspec文件中添加subspec即可,比如
Pod::Spec.new do |s|
s.name = 'BaseClass'
s.version = '1.1.0'
s.summary = 'BaseClass.這里是一些公共類'
s.subspec 'Base' do |sb|
sb.source_files = 'BaseClass/Classes/Base/**/*'
end
s.subspec 'Category' do |sb|
sb.source_files = 'BaseClass/Classes/Category/**/*'
end
s.subspec 'Network' do |sb|
sb.source_files = 'BaseClass/Classes/Network/**/*'
#因為Network這個類庫對AFNetworking、SDWebImage和Category有依賴
sb.dependency 'AFNetworking'
sb.dependency 'SDWebImage'
sb.dependency 'BaseClass/Category'
end
s.subspec 'Tool' do |sb|
sb.source_files = 'BaseClass/Classes/Tool/**/*'
end
當(dāng)我們打上標(biāo)簽并且執(zhí)行pod repo push privateSpec privateLib.podspec之后在終端中執(zhí)行pod search BaseClass
-> BaseClass (1.1.0)
BaseClass.這里是一些公共類
pod 'XMGFMBase', '~> 1.1.0'
- Homepage: https://coding.net/u/Guanzp/p/BaseClass
- Source: https://git.coding.net/Guanzp/BaseClass.git
- Versions: 1.1.0, 1.0.0, 0.1.0 [privateSpec repo]
- Subspecs:
- BaseClass/Base (1.1.0)
- BaseClass/Category (1.1.0)
- BaseClass/Network (1.1.0)
- BaseClass/Tool (1.1.0)
是不是很神奇?哈哈,假如以后我們只想用BaseClass中的某一個組件而又不想導(dǎo)入整個BaseClass,那么我們只需要在podfile文件中導(dǎo)入該子 組件 即可。