热门搜索 :
考研考公
您的当前位置:首页正文

Pods依赖库快速开发入门

来源:东饰资讯网

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

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

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

创建一个Pod Repo

通过模板创建

pod lib create STDemoKit

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

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


手动创建

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

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

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

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

验证podspec有效性命令:

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

提交podspec命令:

pod repo push 索引库名 STDebugConsole.podspec

Repo添加文件依赖

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

添加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, 一个可以解决第三方动态库, 一个可以添加本身库依赖的系统库。

那么我们打开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)

开发库时候的目录分级:

JSONModel源码中目录

引用库时候的目录分级:

JSONModel引入后目录
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}'
     = '-Wno-incomplete-implementation -Wno-missing-prototypes'
    facebook.dependency 'Facebook-iOS-SDK'
end

# ...
end

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

总结

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

参考文献

Top