用 CocoaPods 私有库提高团队的整体效率

swift 发布于 2019年10月18日

今天和大家聊一下 CocoaPods 一个有用的特性,私有 Pod。 在一个团队中,随着开发的项目规模越来越大,一定会积累出很多常用的代码。 比如网络访问,一些工具类等。 好一点的做法是将他们抽离出来放到公共空间,这样下次再需要相关能力的时候,就不用费力的在重复造轮子,特别是有一定规模的团队,会提高很多开发效率。

CocoaPods 作为目前 iOS 开发最流行的包管理工具之一,同样也提供了类似的能力。 以往大家在用 CocoaPods 的时候,可能更多的是用它来管理第三方库。 而 CocoaPods 的私有 Pod 能力可以帮助你用 CocoaPods 的方式,管理你团队内部的库。下面我们就来看一个实际例子。

创建 Pod 库

比如我们要开发一个叫做 DeviceHelper,把常用的设备操作相关的代码封装起来。那么先用这条命令创建一个 pod 库:

pod lib create DeviceHelper

执行完这条命令后,会提示一系列问题, 只需要按照自己的情况配置就好:

上面的截图中看到,创建 pod 库时,会让你填写平台,语言,是否添加 Demo 示例应用等等。 填写完毕后,会自动打开新创建的 Xcode 项目, 结构如下:

pod lib create 会为我们创建一个 Workspace,里面包含两个 Project, DeviceHelper 是我们 Pod 库的 Demo 项目, Pods 是我们实际开发的库的代码。

我们可以修改 Pods/Development Pods/DeviceHelper/ReplaceMe.swift 这个文件,首先将它重命名为 DeviceHelper.swift, 然后写入如下代码:

public class DeviceHelper {

static func isPhoneX () -> Bool{

if UIDevice().userInterfaceIdiom == .phone {
if UIScreen.main.nativeBounds.height == 2436 {
return true
}
}
return false
}

}

这里只为了说明如何创建 Pod 的流程,代码只做演示之用,所以比较简单。 接下来可以在 Demo 工程中引用这个库:

编辑 ViewController.swift:

import UIKit
import DeviceHelper

class ViewController: UIViewController {

override func viewDidLoad() {
super.viewDidLoad()

print(DeviceHelper.isPhoneX())

}

}

这里面直接把 DeviceHelper 的调用结果输出到命令行中。 我们直接运行 Demo 工程就可以看到结果了。 至此一个 Pod 库的开发和调试流程就演示完了。

准备发布

开发和调试完成后,就可以发布 Pod 库了。 这里面多说一下 CocoaPods 的运作原理,我们平常使用的各种第三方库的元信息都储存在 CocoaPodsmaster 库中,这个库其实就是一个普通的 Github 仓库,地址是: https://github.com/CocoaPods/Specs

我们可以看一下 master 库中存放的内容:

可以看到,master 仓库中分类了很多文件夹,任选一个文件夹进入里面,可以看到扩展名为 .podspec.json 的文件:

这个文件中存放了这个库的元信息, 比如它的版本,代码下载地址等等。 实际上我们每次运行 pod install 命令后,CocoaPods 先从 master 库中将我们要安装的三方库的元信息查找出来,然后再根据元信息中存储的代码地址,版本信息等,去下载真正的库。

以上就是 CocoaPods 的基本运作原理了, 可以再看一下我们的 Pod 工程:

也存在这样一个文件 DeviceHelper.podspec, 我们在发布之前也需要对它进行一些编辑:

Pod::Spec.new do |s|
s.name = 'DeviceHelper'
s.version = '0.1.0'
s.summary = '一个演示用的项目'
s.description = <<-DESC
用于演示 CocoaPods 的运作原理
DESC


s.homepage = 'https://github.com/swiftcafex'
s.license = { :type => 'MIT', :file => 'LICENSE' }
s.author = { 'swiftcafex' => 'swiftcafex@gmail.com' }
s.source = { :git => 'https://github.com/swiftcafex/DeviceHelper.git', :tag => s.version.to_s }

s.ios.deployment_target = '8.0'

s.source_files = 'DeviceHelper/Classes/**/*'
end

这个文件的内容是一段 Ruby 代码(CocoaPods 自身是基于 Ruby 语言的), 其中有几个属性需要介绍下:

s.summary - 这个库的一个简短描述,必须填写,而且不能和默认值重复,否则不能通过验证。 s.description - 这个库的详细描述,同上,必须填写。 s.homepage - 这个库的主页地址,也必须自定义填写。 s.source - 这个最重要,库的源代码地址。

创建 Release 版本

上面的内容就是一个有效的 podspec 文件了。在发布之前,我们还需要进行一个准备工作,就是创建 Release 版本。

这里以 Github 私有仓库为例(用私有仓库,是因为我们要创建的私有 Pod 组件,不发布到 master 库上面), 当然并不仅限于 Github,任何 Git 服务端都可以。

进入项目主页然后点击 Release 按钮:

接下来,按照我们 podspec 文件中写的版本号,创建一个 release 版本:

我们的 podspec 中定义的版本是 0.1.0, 接下来就这样填写:

然后点下下面的绿色 Publish release 按钮, 就完成了源代码版本的发布:

验证 podspec 文件

在发布之前,我们需要对刚刚编辑的 podspec 文件进行验证。 如果没有执行刚才的创建 Release 版本,验证就会不通过,这也是为什么要创建 Release 版本的原因。

在 Pod 项目的根目录中,执行命令:

pod spec lint

如果你用的是 swift 语言,有可能会提示这个错误:

CocoaPods 需要你指定这个库的 Swift 版本, 只需要按照它提示的,创建一个文件名为 .swift-version 的隐藏文件即可:

echo "4.0" > .swift-version

PS: echo 命令简单解释一下,它会把你指定的内容输出的当前指定的流中。 我们指定的内容是 "4.0" 这个字符串, > .swift-version 这个符号代表将当前的输出流导向到文件名为 .swift-version 的文件。 一句话就是创建一个文件名为 .swift-version 的文件,包含字符串 "4.0"。

如果准备工作都就绪,刚才说到的 Release 版本也正确创建的话,你就会看到一条验证通过的消息:

创建元信息库

因为我们要创建的是私有 Pod 库,肯定不会将元信息发布到 CocoaPodsmaster 库中,而是发布到我们自己控制的私有元信息库中。这个过程也很简单,还是以 Github 为例(任何 Git 服务端也都可以), 先创建一个我们自己的仓库:

仓库创建好之后,使用这条命令将仓库添加到 CocoaPods 本地的仓库列表中:

pod repo add swiftcafe https://github.com/swiftcafex/PodSepcs

添加完成后,再输入 pod repo 命令, 就可以看到列出的现有仓库:

这里列出了 CocoaPodsmaster 主仓库, 还有我们自己的私有仓库。

本地仓库设置好之后, 我们还需要将我们刚刚创建的 DeviceHelper Pod 库的 podspec 元信息文件推送进来,还是在 Pod 库工程的根目录运行:

pod repo push swiftcafe DeviceHelper.podspec

DeviceHelper.podspec 是我们前面编辑的 .podspec 文件,包含了这个私有库的版本,源代码地址,描述等信息。 swiftcafe 是我们刚刚加入的私有元信息库。

pod repo push 这条命令做的就是将我们创建的 Pod 库的元信息,推送到我们自己的私有元信息库中,而不是公共的 master 库。 这样就保证了这些组件只有我们自己有权限的人才能访问。

推送成功后,命令行中会显示如下提示:

再回到我们刚刚创建的私有元信息仓库中,也能看到 DeviceHelper 这个库的元信息被推送上来了:

至此,我们的 CocoaPods 私有模块化工作就完成了。

在项目中使用

最后,我们来看看其他项目如何引用这个私有 Pod, 我们随意创建一个工程, 然后在它的根目录中用 pod init 命令初始化一个 Podfile,并且做一些修改:

source "https://github.com/swiftcafex/PodSepcs"

target 'test' do

use_frameworks!

pod 'DeviceHelper'

end

与我们平常使用的 Podfile 文件唯一不同的是,它的第一行多了一个 source, 用来指定我们要从哪个元信息仓库抓取内容。 我们这里指定了刚刚创建的私有仓库,这样下面的 DeviceHelper 库就能正确的找到了。 前提是你需要有元信息库和 DeviceHelper 自身库的 Github 权限。

我们运行 pod install, 可以看到 DeviceHelper 被正确的安装了:

总结

以上就是创建一个私有 Pod 的基本流程了。 当然,这里面还是有很多可以思考的地方,比如一个团队每个人的开发机上如何统一的配置私有库的访问权限,或者如何摆脱 Github 服务,通过自己的 Git 服务和 CocoaPods 交互。

CocoaPods 的私有库功能给我们提供了一个很低成本实现团队内部组件化的一个解决方案。从上面的介绍也不难看出,CocoaPods 本身并不只是一个中心化的包管理平台,它其实还是一套设计机制,通过 Git 仓库,可以非常快的速度实现自己的整套 Pod 服务。

对于你的开发团队,特别是已经长期积累了很多代码的情况,通过类似的机制将已有的代码进行必要的整理,对整个团队的开发效率都会有一个很大的提升。


如果你觉得这篇文章有帮助,还可以关注微信公众号 swift-cafe,会有更多我的原创内容分享给你~

本站文章均为原创内容,如需转载请注明出处,谢谢。
关注微信公众号
发现更多精彩
swift-cafe