Pods依赖库快速开发入门

CocoaPods是所有iOS开发熟知的一个第三方类库依赖管理工具。只要稍微有些经验的iOS开发者都会使用三方依赖库管理工具来管理工程依赖, CocoaPods是目前最火热权威的管理工具。

CocoaPods的基本使用现在网站上遍历都是的教程, 官方文档的简明教程也足够清晰明朗。本篇文章主要告诉大家如何去开发一个CocoaPods依赖库, 重点内容分三块:

  1. 如何创建一个Pod Repo
  2. 如何将库提交到中央Spec库或私有Spec库中供大家使用
  3. 如何在开发中添加resource、framework以及其它依赖

创建一个Pod Repo

通过模板创建

关于如何创建一个Pod Repo, @wtlucky_星魂丨飘渺灬的一篇博文使用Cocoapods创建私有podspec里有介绍如何使用pod lib create (libName)去创建一个Pod Repo。简单示例如下:

pod lib create STDemoKit

执行如上命令, 根据lib需要选择对应的语言(Objc/Swift)、是否需要生产示例项目以及是否需要基础测试target等选项, 就会生产一个默认的名叫STDemoKit的Pod库。

就这么一行命令, 自己动手敲一把, 绝对印象会加深很多的~


手动创建

CocoaPods会利用自带的模板去创建, 非常简单方便使用, 本文就不再赘述, 只是描述下如何手动去创建一个Pod Repo。

手动创建CocoaPods库的关键在于描述文件podspec, 手动创建私有库的第一步就是复制或新建一个podspec。(podspec格式描述固定, 直接从官方网站复制来的快)

手动创建私有库的关键两行代码在于:

Pod::Spec.new do |spec|
  spec.name          = 'STDemoKit'
  spec.source_files  = 'MyLib/Classes/**/*.{h,m,c}'
## 补充必要的一些描述, 用于通过lint校验
end

在podspec所在文件夹下创建一个名为MyLib的文件夹, 并在MyLib文件夹下创建一个名为Classes*的文件夹, 放置自己实现的示例代码在该文件夹下。

自己动手创建podspec示例

通过上述的步骤, 已经创建了自己的pod库, 然后需要的是本地测试, 测试自己的创建的本地库需要再创建一个Example工程, 同时在Podfile中指定本地库所在位置, 示例如下:

pod "STDemoKit", :path => "~/目标库地址"

在Podfile中指定本地的库地址后, 执行下pod install即可测试自己创建的库了。

如何提交库到Spec

在告诉读者怎么提交库到Spec的时候, 需要问大家一个问题: 什么是Spec?

我引用和翻译一下官方文档的描述:

PodSpec(Spec)是一个用来描述一个固定版本的Pod库的文件, 根据版本推移, 一个库会有多个PodSpec(Spec)文件去描述它。该描文件描述了该版本库的引用地址、需要引用的文件、应用编译配置项以及类似库名字、库版本和描述相关的其它元数据。

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模板创建的库的podspec描述文件如下:

PodSepc文件示例

回归主题: 怎么提交Spec

使用Cocoapods创建私有podspec中有一个章节《向Spec Repo提交podspec》, 该章节有<font color='red'>详细</font>的说明介绍如果向Pod库提交podspec, 本文只是列出两个命令, 方便大家快速查阅, 分别是提交podspec验证podspec有效性的命令。

一般情况下, 都需要先执行下有效性验证才会去向Spec库提交自己的podspec, 这个是开发者的基本素质吧~

验证podspec有效性命令:

# 需要在podspec文件所在目录下执行
pod lib lint

提交podspec命令:

pod repo push 索引库名 STDebugConsole.podspec

补充:
关于索引库, 有区分官方库和非官方库。一般大公司都会维护一个官方索引库自有索引库官方索引库一般是git官方库的一个镜像, 为了加快公司内对库索引更新的速度。自由索引库一般维护了公司业务产品自有依赖的基础组件和业务组件。

Repo添加文件依赖

在实际工程开发过程中, 我发现很多童鞋都不了解怎么去添加资源文件到工程中, 其实我自己一开始也不太了解哈, 后面在工程应用中逐渐熟悉起来的。我结合自己的使用经验以及参考CocoaPods官方描述文档, 在这里简单描述一下。

我先举几个常用的实际场景:

添加framework

假设我们已经通过前面说的模板去创建了一个私有库STShareKit, 然后我需要往STShareKit库添加分享库ShareSDK.framework, 我是不是直接和开发普通工程一样直接往文件目录一拖就好了呢? <font color='orange'>实践证明这种方式是不可取的</font>。

因为STShareKit本身是一个库, 如果直接网里面拖framework, 只会把对应的target引用写进项目的pbproj下, 只是一次性的被根项目引用, 并且不能被库本身引用, 因此通过纯粹的拖动是不可取的。(其实本人觉得如果Xcode做的智能点, 应该是可以解决这个问题的, 吐槽下)

参考前面PodSepc文件示例的podspec文件描述, 核心解决关键在于下述代码:

s.vendored_frameworks = [
    'Pod/Frameworks/*.framework'
]
s.frameworks = 'UIKit', 'Foundation'

通过在podspec中添加上述两个文件描述并执行一次pod install, 一个可以解决第三方动态库, 一个可以添加本身库依赖的系统库。

大家会不会好奇通过podspec描述的文件是怎么添加上去的, 是怎么被主工程和库给引用的。对Xcode环境配置熟悉的童鞋肯定能够猜到, 环境配置不是在pbproj描述下就是通过xcconfig进行注入的。如果大家对xcconfig想要进一步了解, 请大家移步我之前写的文章《iOS开发必备 - 环境变量配置(Debug & Release)》

那么我们打开STShareKit.xcconfig文件进行一探究竟。(需要在引用工程执行完pod install命令才会生成)。

FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/../Pod/Frameworks"
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Private" # ...此处有省略

第一行FRAMEWORK_SEARCH_PATHS基本已经解除了大家的困惑了吧~

添加资源文件

添加资源文件的方式和添加第三方framework的方式相同, 核心解决关键在下述代码:

s.resource_bundles = {
    'STShareKit' => ['Pod/Assets/*.png']
}

这里有个特殊的地方, 通过上述写法书写的方式在pod命令执行过程中会创建一个名为ONESDriver.bundle的bundle来包含所有防止在物理目录Pod/Assets下的资源文件。

添加资源文件还有另外一种方式(不推荐):

s.resources = 'Pod/Assets/**/*'

通过这种方式写法会被所有的资源文件不添加bundle直接copy进入主工程, 很容易发生重名冲突等问题, 不建议用这个写法~

补充: 大家如果把上述描述文件修改和下面一样, 大家猜猜会发生什么事情呢? (库名为STShareKit)

s.resource_bundles = {
    'STShareUI' => ['Pod/Assets/*.png']
}

接下来抛给大家一个问题, 资源文件是怎么添加到主工程里的, 是通过xcconfig吗?
我一开始以为是通过xcconfig进行配置, 后面并没有找到对应的配置项目, 在工程下面的Build Phases, CocoaPods会默认添加一个执行脚本:

Build Phases拷贝脚本

打开Target Support Files目录下Pods文件夹下的Pods-resources.sh脚本文件, 全局搜索STShareKit.bundle, 可以发现在脚本里有如下代码:

install_resource "${BUILT_PRODUCTS_DIR}/STShareKit.bundle"

看到这行代码基本已经解释了整个bundle是怎么进去到主工程里的了, 具体的细节请大家自行研究install_resource的实现。

源代码分目录(区分group)

做个私有库开发或者细心的童鞋会发现, 本身在开发库时候明明已经区分了物理目录的, 但是在引用工程里的Pods文件夹却是平铺展开的。对于处女座的开发者来说, 都是一怔灾难, 平铺看上怎么都是别扭的。以知名库JSONModel为例子:

开发库时候的目录分级:

JSONModel源码中目录

引用库时候的目录分级:

JSONModel引入后目录

是不是看到这个平级目录很抓狂~ 官方Guide来解救有代码整齐强迫症的童鞋们了, 在A specification with subspecs章节, 有如下的一个样本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

呵呵, 有强迫症的童鞋是否已经找到了救星了呢? 通过描述subspec来对代码进行不同的层级区分, 这样使得引用的库能够有一定的层次感, 阅读和逻辑结构更加清晰。

想要了解的更加清晰, 可以参考知名库AFNetworkingpodspec实现以及引用时候其生产的目录结构!

总结

关于如何使用如何使用CocoaPods创建私有库, 个人感觉使用Cocoapods创建私有podspec已经写的非常的详细, 本篇文章的意义不大。本篇文章对于开发私有库时候的文件等资源文件添加的细节进行了一些补充, 方便大家更加快速的入门, 对于各路高手来说, 这篇文章只有带人引路的作用。

PS: 水平有限, 有错误的地方请及时指出~

参考文献

  1. 使用Cocoapods创建私有podspec
  2. CocoaPods官方指南
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,657评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,662评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,143评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,732评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,837评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,036评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,126评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,868评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,315评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,641评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,773评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,470评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,126评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,859评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,095评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,584评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,676评论 2 351

推荐阅读更多精彩内容