CocoaPods是所有iOS開發(fā)熟知的一個(gè)第三方類庫依賴管理工具洲守。只要稍微有些經(jīng)驗(yàn)的iOS開發(fā)者都會(huì)使用三方依賴庫管理工具來管理工程依賴, CocoaPods是目前最火熱權(quán)威的管理工具匾鸥。
CocoaPods的基本使用現(xiàn)在網(wǎng)站上遍歷都是的教程, 官方文檔的簡明教程也足夠清晰明朗仅叫。本篇文章主要告訴大家如何去開發(fā)一個(gè)CocoaPods依賴庫, 重點(diǎn)內(nèi)容分三塊:
- 如何創(chuàng)建一個(gè)Pod Repo
- 如何將庫提交到中央Spec庫或私有Spec庫中供大家使用
- 如何在開發(fā)中添加resource旗们、framework以及其它依賴
創(chuàng)建一個(gè)Pod Repo
通過模板創(chuàng)建
關(guān)于如何創(chuàng)建一個(gè)Pod Repo, @wtlucky_星魂丨飄渺灬的一篇博文使用Cocoapods創(chuàng)建私有podspec里有介紹如何使用pod lib create (libName)
去創(chuàng)建一個(gè)Pod Repo佑刷。簡單示例如下:
pod lib create STDemoKit
執(zhí)行如上命令, 根據(jù)lib需要選擇對應(yīng)的語言(Objc/Swift)原环、是否需要生產(chǎn)示例項(xiàng)目以及是否需要基礎(chǔ)測試target等選項(xiàng), 就會(huì)生產(chǎn)一個(gè)默認(rèn)的名叫STDemoKit
的Pod庫箕肃。
就這么一行命令, 自己動(dòng)手敲一把, 絕對印象會(huì)加深很多的~
手動(dòng)創(chuàng)建
CocoaPods會(huì)利用自帶的模板去創(chuàng)建, 非常簡單方便使用, 本文就不再贅述, 只是描述下如何手動(dòng)去創(chuàng)建一個(gè)Pod Repo。
手動(dòng)創(chuàng)建CocoaPods庫的關(guān)鍵在于描述文件podspec, 手動(dòng)創(chuàng)建私有庫的第一步就是復(fù)制或新建一個(gè)podspec粹懒。(podspec格式描述固定, 直接從官方網(wǎng)站復(fù)制來的快)
手動(dòng)創(chuàng)建私有庫的關(guān)鍵兩行代碼在于:
Pod::Spec.new do |spec|
spec.name = 'STDemoKit'
spec.source_files = 'MyLib/Classes/**/*.{h,m,c}'
## 補(bǔ)充必要的一些描述, 用于通過lint校驗(yàn)
end
在podspec所在文件夾下創(chuàng)建一個(gè)名為MyLib的文件夾, 并在MyLib文件夾下創(chuàng)建一個(gè)名為Classes*的文件夾, 放置自己實(shí)現(xiàn)的示例代碼在該文件夾下重付。
通過上述的步驟, 已經(jīng)創(chuàng)建了自己的pod庫, 然后需要的是本地測試, 測試自己的創(chuàng)建的本地庫需要再創(chuàng)建一個(gè)Example工程, 同時(shí)在Podfile中指定本地庫所在位置, 示例如下:
pod "STDemoKit", :path => "~/目標(biāo)庫地址"
在Podfile中指定本地的庫地址后, 執(zhí)行下pod install
即可測試自己創(chuàng)建的庫了。
如何提交庫到Spec
在告訴讀者怎么提交庫到Spec的時(shí)候, 需要問大家一個(gè)問題: 什么是Spec?
我引用和翻譯一下官方文檔的描述:
PodSpec(Spec)是一個(gè)用來描述一個(gè)固定版本的Pod庫的文件, 根據(jù)版本推移, 一個(gè)庫會(huì)有多個(gè)PodSpec(Spec)文件去描述它凫乖。該描文件描述了該版本庫的引用地址确垫、需要引用的文件弓颈、應(yīng)用編譯配置項(xiàng)以及類似庫名字、庫版本和描述相關(guān)的其它元數(shù)據(jù)删掀。
A Podspec, or Spec, describes a version of a Pod library. One Pod, over the course of time, will have many Specs. It includes details about where the source should be fetched from, what files to use, the build settings to apply, and other general metadata such as its name, version, and description.
利用CocoaPods模板創(chuàng)建的庫的podspec描述文件如下:
回歸主題: 怎么提交Spec
使用Cocoapods創(chuàng)建私有podspec中有一個(gè)章節(jié)《向Spec Repo提交podspec》, 該章節(jié)有<font color='red'>詳細(xì)</font>的說明介紹如果向Pod庫提交podspec, 本文只是列出兩個(gè)命令, 方便大家快速查閱, 分別是提交podspec和驗(yàn)證podspec有效性的命令翔冀。
一般情況下, 都需要先執(zhí)行下有效性驗(yàn)證才會(huì)去向Spec庫提交自己的podspec, 這個(gè)是開發(fā)者的基本素質(zhì)吧~
驗(yàn)證podspec有效性命令:
# 需要在podspec文件所在目錄下執(zhí)行
pod lib lint
提交podspec命令:
pod repo push 索引庫名 STDebugConsole.podspec
補(bǔ)充:
關(guān)于索引庫, 有區(qū)分官方庫和非官方庫。一般大公司都會(huì)維護(hù)一個(gè)官方索引庫和自有索引庫披泪。官方索引庫一般是git官方庫的一個(gè)鏡像, 為了加快公司內(nèi)對庫索引更新的速度纤子。自由索引庫一般維護(hù)了公司業(yè)務(wù)產(chǎn)品自有依賴的基礎(chǔ)組件和業(yè)務(wù)組件。
Repo添加文件依賴
在實(shí)際工程開發(fā)過程中, 我發(fā)現(xiàn)很多童鞋都不了解怎么去添加資源文件到工程中, 其實(shí)我自己一開始也不太了解哈, 后面在工程應(yīng)用中逐漸熟悉起來的款票。我結(jié)合自己的使用經(jīng)驗(yàn)以及參考CocoaPods官方描述文檔, 在這里簡單描述一下控硼。
我先舉幾個(gè)常用的實(shí)際場景:
添加framework
假設(shè)我們已經(jīng)通過前面說的模板去創(chuàng)建了一個(gè)私有庫STShareKit, 然后我需要往STShareKit庫添加分享庫ShareSDK.framework, 我是不是直接和開發(fā)普通工程一樣直接往文件目錄一拖就好了呢? <font color='orange'>實(shí)踐證明這種方式是不可取的</font>。
因?yàn)镾TShareKit本身是一個(gè)庫, 如果直接網(wǎng)里面拖framework, 只會(huì)把對應(yīng)的target引用寫進(jìn)項(xiàng)目的pbproj下, 只是一次性的被根項(xiàng)目引用, 并且不能被庫本身引用, 因此通過純粹的拖動(dòng)是不可取的艾少。(其實(shí)本人覺得如果Xcode做的智能點(diǎn), 應(yīng)該是可以解決這個(gè)問題的, 吐槽下)
參考前面PodSepc文件示例的podspec文件描述, 核心解決關(guān)鍵在于下述代碼:
s.vendored_frameworks = [
'Pod/Frameworks/*.framework'
]
s.frameworks = 'UIKit', 'Foundation'
通過在podspec中添加上述兩個(gè)文件描述并執(zhí)行一次pod install
, 一個(gè)可以解決第三方動(dòng)態(tài)庫, 一個(gè)可以添加本身庫依賴的系統(tǒng)庫卡乾。
大家會(huì)不會(huì)好奇通過podspec描述的文件是怎么添加上去的, 是怎么被主工程和庫給引用的。對Xcode環(huán)境配置熟悉的童鞋肯定能夠猜到, 環(huán)境配置不是在pbproj描述下就是通過xcconfig進(jìn)行注入的缚够。如果大家對xcconfig想要進(jìn)一步了解, 請大家移步我之前寫的文章《iOS開發(fā)必備 - 環(huán)境變量配置(Debug & Release)》幔妨。
那么我們打開STShareKit.xcconfig文件進(jìn)行一探究竟。(需要在引用工程執(zhí)行完pod install
命令才會(huì)生成)谍椅。
FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/../Pod/Frameworks"
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Private" # ...此處有省略
第一行FRAMEWORK_SEARCH_PATHS基本已經(jīng)解除了大家的困惑了吧~
添加資源文件
添加資源文件的方式和添加第三方framework的方式相同, 核心解決關(guān)鍵在下述代碼:
s.resource_bundles = {
'STShareKit' => ['Pod/Assets/*.png']
}
這里有個(gè)特殊的地方, 通過上述寫法書寫的方式在pod
命令執(zhí)行過程中會(huì)創(chuàng)建一個(gè)名為ONESDriver.bundle的bundle來包含所有防止在物理目錄Pod/Assets
下的資源文件误堡。
添加資源文件還有另外一種方式(不推薦):
s.resources = 'Pod/Assets/**/*'
通過這種方式寫法會(huì)被所有的資源文件不添加bundle直接copy進(jìn)入主工程, 很容易發(fā)生重名沖突等問題, 不建議用這個(gè)寫法~
補(bǔ)充: 大家如果把上述描述文件修改和下面一樣, 大家猜猜會(huì)發(fā)生什么事情呢? (庫名為STShareKit)
s.resource_bundles = {
'STShareUI' => ['Pod/Assets/*.png']
}
接下來拋給大家一個(gè)問題, 資源文件是怎么添加到主工程里的, 是通過xcconfig嗎?
我一開始以為是通過xcconfig進(jìn)行配置, 后面并沒有找到對應(yīng)的配置項(xiàng)目, 在工程下面的Build Phases, CocoaPods會(huì)默認(rèn)添加一個(gè)執(zhí)行腳本:
打開Target Support Files目錄下Pods文件夾下的Pods-resources.sh腳本文件, 全局搜索STShareKit.bundle, 可以發(fā)現(xiàn)在腳本里有如下代碼:
install_resource "${BUILT_PRODUCTS_DIR}/STShareKit.bundle"
看到這行代碼基本已經(jīng)解釋了整個(gè)bundle是怎么進(jìn)去到主工程里的了, 具體的細(xì)節(jié)請大家自行研究install_resource的實(shí)現(xiàn)。
源代碼分目錄(區(qū)分group)
做個(gè)私有庫開發(fā)或者細(xì)心的童鞋會(huì)發(fā)現(xiàn), 本身在開發(fā)庫時(shí)候明明已經(jīng)區(qū)分了物理目錄的, 但是在引用工程里的Pods文件夾卻是平鋪展開的毯辅。對于處女座的開發(fā)者來說, 都是一怔災(zāi)難, 平鋪看上怎么都是別扭的埂伦。以知名庫JSONModel為例子:
開發(fā)庫時(shí)候的目錄分級:
引用庫時(shí)候的目錄分級:
是不是看到這個(gè)平級目錄很抓狂~ 官方Guide來解救有代碼整齊強(qiáng)迫癥的童鞋們了, 在A specification with subspecs章節(jié), 有如下的一個(gè)樣本podspec
Pod::Spec.new do |spec|
spec.name = 'ShareKit'
spec.source_files = 'Classes/ShareKit/{Configuration,Core,Customize UI,UI}/**/*.{h,m,c}'
# ...
spec.subspec 'Evernote' do |evernote|
evernote.source_files = 'Classes/ShareKit/Sharers/Services/Evernote/**/*.{h,m}'
end
spec.subspec 'Facebook' do |facebook|
facebook.source_files = 'Classes/ShareKit/Sharers/Services/Facebook/**/*.{h,m}'
facebook.compiler_flags = '-Wno-incomplete-implementation -Wno-missing-prototypes'
facebook.dependency 'Facebook-iOS-SDK'
end
# ...
end
呵呵, 有強(qiáng)迫癥的童鞋是否已經(jīng)找到了救星了呢? 通過描述subspec來對代碼進(jìn)行不同的層級區(qū)分, 這樣使得引用的庫能夠有一定的層次感, 閱讀和邏輯結(jié)構(gòu)更加清晰煞额。
想要了解的更加清晰, 可以參考知名庫AFNetworking的podspec實(shí)現(xiàn)以及引用時(shí)候其生產(chǎn)的目錄結(jié)構(gòu)!
總結(jié)
關(guān)于如何使用如何使用CocoaPods創(chuàng)建私有庫, 個(gè)人感覺使用Cocoapods創(chuàng)建私有podspec已經(jīng)寫的非常的詳細(xì), 本篇文章的意義不大思恐。本篇文章對于開發(fā)私有庫時(shí)候的文件等資源文件添加的細(xì)節(jié)進(jìn)行了一些補(bǔ)充, 方便大家更加快速的入門, 對于各路高手來說, 這篇文章只有帶人引路的作用。
PS: 水平有限, 有錯(cuò)誤的地方請及時(shí)指出~