制作 CocoaPods 依赖库
学会使用别人的 Pods 依赖库以后, 你一定对创建自己的依赖库很有兴趣吧,现在我们就来尝试一下,以一个简单 O2View 为例自己创建一个 Pods 依赖库,这里我会使用 Swift 2.0 来写这个例子。
CocoaPods 是托管在 github 上的,所有的 Pods 也都是托管在 github 上,因此我们首先需要创建一个属于自己的 github 仓库,如下图所示:
上图中标识出了6处地方
上面各项根据大家需要填写完毕后,点击 Create repository 按钮即可,创建成功后如下所示:
为了方便向仓库中删减内容,需要将仓库 clone 到本地,这里有多种操作方式,可以选择你喜欢的一种,但是为了方便这边选择使用命令行。首先需要切换到你想在本地存储的目录,然后再 clone ,假设你放在用户的根目录上:
cd ~
git clone https://github.com/marklin2012/O2View.git
完成后,我们进入到 ~/O2View
目录中应该可以看到目录结构如下:
|____LICENSE
|____README.md
其实还有一个隐藏的 .git 文件,后续我们的所有文件都在这个目录底下进行。
创建 Pods 依赖库就是为了方便别人使用我们的成果,比如我想共享给大家的O2View类,那这个类自然必不可少,我们把这个类放入一个 O2View 的目录中:
顺便看看 O2View.swift 主要内容:
import UIKit
public class O2View: UIView {
public override init(frame: CGRect) {
super.init(frame: frame)
backgroundColor = UIColor.redColor()
}
required public init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
每个 Pods 依赖库必须有且仅有一个名称和依赖库名保持一致,后缀名为 .podspec 的描述文件。这里我们依赖库的描述文件名称应该为 O2View.podspec
。
创建这个文件有两种途径:
我们使用命令行:
pod spec create O2View
创建出 O2View.podspec 文件后,我们打开可以发现,该文件是 ruby 文件,里面有很多的内容,但是大多数都是我们不需要的,所以我们只需要根据项目的情况保留关键的一些内容就行:
Pod::Spec.new do |s|
s.name = "O2View" #名称
s.version = "0.0.1" #版本号
s.summary = "Just testing" #简短介绍
s.description = <<-DESC
私有Pods测试
* Markdown 格式
DESC
s.homepage = "http://aoto.io/"
# s.screenshots = "www.example.com/screenshots_1.gif"
s.license = "MIT" #开源协议
s.author = { "linyi31" => "[email protected]" }
s.source = { :git => "https://github.com/marklin2012/O2View.git" }
## 这里不支持ssh的地址,只支持HTTP和HTTPS,最好使用HTTPS
## 正常情况下我们会使用稳定的tag版本来访问,如果是在开发测试的时候,不需要发布release版本,直接指向git地址使用
## 待测试通过完成后我们再发布指定release版本,使用如下方式
#s.source = { :git => "http://EXAMPLE/O2View.git", :tag => version }
s.platform = :ios, "9.0" #支持的平台及版本,这里我们呢用swift,直接上9.0
s.requires_arc = true #是否使用ARC
s.source_files = "O2View/*.swift" #OC可以使用类似这样"Classes/**/*.{h,m}"
s.frameworks = 'UIKit', 'QuartzCore', 'Foundation' #所需的framework,多个用逗号隔开
s.module_name = 'O2View' #模块名称
# s.dependency "JSONKit", "~> 1.4" #依赖关系,该项目所依赖的其他库,如果有多个可以写多个 s.dependency
end
为了快速教会别人使用我们的 Pods 依赖库,通常需要提供一个 demo 工程。我们创建了一个名为 O2ViewDemo 的工程来演示 O2View 的使用,如下图所示:
使用 github 的人应该都熟悉这个文件,它使一个成功的 github 仓库必不可少的一部分,使用 markdown 对仓库进行详细说明。
CocoaPods 强制要求所有的 Pods 依赖库都必须有 license 文件,否则验证不会通过。 license 文件有很多中,详情可以参考 tldrlegal。前面我们已经选择创建了一个 MIT 类型的 license。
以上的5个文件是创建 Pods 依赖库所需的基础文件,当然 Demo 工程没有添加也没关系。添加完这些内容后,我们本地仓库目录就变成这个样子:
经过前面步骤,我们已将在本地的 git 仓库添加了不少文件,现在我们只要将他们提交到 github 上就可以。在此之前我们需要对刚才添加的 pod 进行一下验证:
pod lib lint
运行之后可能会得到下面的警告:
-> O2View (0.0.1)
- WARN | source: Git sources should specify a tag.
[!] O2View did not pass validation, due to 1 warning (but you can use `--allow-warnings` to ignore it) and All results apply only to public specs, but you can use `--private` to ignore them if linting the specification for a private pod..
You can use the `--no-clean` option to inspect any issue.
由于我们现在还没有正式生成 release 版本, github 上并没有任何 tag,所以我们刚才填写 .podspec 文件填写 git 地址的时候没有填写指定 tag (上面文件的注释中有提到),解决方法我们可以先执行忽略警告的命令:
pod lib lint --allow-warnings
如果成功会出现如下输出:
-> O2View (0.0.1)
- WARN | source: Git sources should specify a tag.
O2View passed validation.
当调试完成了之后,我们需要在 github 上把我们的代码生成相应稳定的 release 版本,到时候我们再回来添加指定 tag 发布就 Ok 了。
验证成功之后,我们只要把代码提交到 github 仓库,就可以了,参考命令:
git add -A && git commit -m "add pod files"
git push origin master
这里主要是 git 的范畴,不做过多叙述。如果前面操作都没有问题的话,github 上应该能看到类似如下内容:
经过前面的步骤,我们的 CocoaPods 依赖库就已经准备好了,但是现在你还不能在你的工程中使用它。如果你想成为一个真正可用的依赖库,还需要最后一步操作:将刚才生产的 podspec 文件提交到 官方的 CocoaPods Specs 中。
没错,我们平时用的能用 pod search
搜到的依赖库都会把它上传到这个仓库中, 也就是说只有将我们的 podspec 文件上传到这里,才能成为一个真正的依赖库,别人才能用!
按照 github 的规则,要想向别人的库中添加文件,就要先 fork 别人的仓库,做相应的修改,再 pullrequest 给仓库的原作者,等到作者审核通过,进行 meger 之后就可以了!
流程大概就是这个样子,具体可以参考:CocoaPods Guides,我们就先不展开详细的叙述了(后面会添加关于这部分的文章)。
除了官方的 specs 之外,我们还可以把 podspec 文件提交到私有的仓库中,详见我们博客的另一篇文章:创建私有的 CocoaPods repo spec 。
打开隐藏目录,可以使用命令:
//打开隐藏的命令:
defaults write com.apple.finder AppleShowAllFiles -bool true
//关闭隐藏的命令:
defaults write com.apple.finder AppleShowAllFiles -bool false
接着需要重启一下 Finder, 可以按住 option + 右键 Finder 图标选择重启。然后打开隐藏目录 .cocoapods (这个目录在你的个人目录底下, ~/.cocoapods
或 /Users/[username]/.cocoapods
)
可以看到上图, .cocoapods 目录下的 repos 其实是 repository (仓库)的缩写。 repos 中存放的时仓库的集合。这里的 master 就是 CocoaPods 官方建立的仓库,也就是我们所谓的公共库。
specs 目录下存放的就是所有提交到 CocoaPods 的开源库的 podspec 文件的集合。
其结构如下图所示:
其组成方式:
specName -- version -- specName.podspec
( master 里现在是 specName.podspec.json,这个 .json 文件就是 podspec 文件加了个后缀。我们可以采用 pod ipc spec
这个命令来将 spec 文件转换成 .json)
那这个文件夹是如何来得呢?其实,这个文件夹是在你安装了 CocoaPods 后,第一次执行 pod install
时, CocoaPods 通过命令 pod setup
来建立的(这条命令会自动执行)。
上述是官方的 repo ,私有库的话可以看下我们前面的翻译或者查看官方文档,但是官方文档有一些过程写的不是特别详细,自己实现的时候遇到了一些坑,特此梳理一下过程,按照官方文档内容实现一个私有的 spec repo 。根据官方的原理,我们只需要创建一个和 master 相类似结构的目录就可以实现私有的 spec repo,当然你可以 fork 一个官方的 repo,但是它包含了太多没有必要地库在里面,这在编译仓库的时候需要浪费大量的时间,所以我们只要自己重新创建一个就可以了。
在你的 git 服务器上创建一个 repo。这里你可以在 github 或者你自己的 git 服务器上实现。公司内部使用的话这里推荐大家使用私有的仓库,但是 github 的私有仓库是要收费的 $7/month (壕请无视 - -!)。大部分公司都是有自己的git服务器,不过一般只能在公司内网使用,或者可以选择Gitlab,Coding, Bitbucket任意一种。我们以在 github 上创建为例:
如图所示,我们在 github 上创建一个空的仓库,命名为 O2Specs ,这个仓库是用来存放我们自己所有的私有库的 spec 文件,就如同官方的 https://github.com/CocoaPods/Specs 是用来存放所有官方的 specs 文件一样。
然后我们就可以执行:
pod repo add REPO_NAME SOURCE_URL
其中的 REPO_NAME 是我们要添加的私有 repo 的名称(这里我们待会填的是: O2Specs),后面是仓库的 git 地址。这里做的其实是创建的工作,也就是在 ~/.cocoapods/repo
目录下添加了一个以你的私有 repo 为名的文件夹,但是并没有添加 spec 文件。
在终端执行命令:
pod repo add O2Specs https://github.com/marklin2012/O2Specs.git
这里用的是 https 地址,当然你也可以用 git 地址,不过这样有可能失败。如果失败,很大因素是你 github 的 ssh 在本地没有配置好,配置方法可以看这里:Generating SSH keys,成功后可以看得到 .cocoapods 目录如下图所示:
至此,我们已经在本地得到我们自己的私有仓库 O2Specs ,这是一个空的仓库。
这个步骤需要我们事先完成 CocoaPods 依赖库的搭建,具体可以查看我们另外一篇教程:制作 CocoaPods 依赖库。如果这里你想先看看效果,也可以直接从 github 上 clone 示例工程继续下面的操作。
让我们进入到上面 clone 的示例工程目录中(或者你自己搭建的依赖库目录中):
打开工程的 podspec 文件:
Pod::Spec.new do |s|
s.name = "O2View" #名称
s.version = "0.0.1" #版本号
s.summary = "Just testing" #简短介绍
s.description = <<-DESC
私有Pods测试
* Markdown 格式
DESC
s.homepage = "http://aotu.io/"
# s.screenshots = "www.example.com/screenshots_1.gif"
s.license = "MIT" #开源协议
s.author = { "linyi31" => "[email protected]" }
s.source = { :git => "https://github.com/marklin2012/O2View.git" }
## 这里不支持ssh的地址,只支持HTTP和HTTPS,最好使用HTTPS
## 正常情况下我们会使用稳定的tag版本来访问,如果是在开发测试的时候,不需要发布release版本,直接指向git地址使用
## 待测试通过完成后我们再发布指定release版本,使用如下方式
#s.source = { :git => "http://EXAMPLE/O2View.git", :tag => s.version }
s.platform = :ios, "9.0" #支持的平台及版本,这里我们呢用swift,直接上9.0
s.requires_arc = true #是否使用ARC
s.source_files = "O2View/*.swift" #OC可以使用类似这样"Classes/**/*.{h,m}"
s.frameworks = 'UIKit', 'QuartzCore', 'Foundation' #所需的framework,多个用逗号隔开
s.module_name = 'O2View' #模块名称
# s.dependency "JSONKit", "~> 1.4" #依赖关系,该项目所依赖的其他库,如果有多个可以写多个 s.dependency
end
这个文件本质上是一个 ruby 文件,这是我们事先已经实现好的依赖库的 podspec 文件,如果前面步骤都正常的话,也就是说我们认为这个 podspec 是合法的话,就可以直接将这些内容 push 到我们本地的 repo 中。为了避免错误,我们可以再验证一下,命令行输入:
pod lib lint
运行之后可能会得到下面的警告:
-> O2View (0.0.1)
- WARN | source: Git sources should specify a tag.
[!] O2View did not pass validation, due to 1 warning (but you can use `--allow-warnings` to ignore it) and All results apply only to public specs, but you can use `--private` to ignore them if linting the specification for a private pod..
You can use the `--no-clean` option to inspect any issue.
由于我们的示例工程还没有生成正式的 release 版本, github 上并没有任何 tag,所以我们刚才填写 .podspec 文件填写 git 地址的时候没有填写指定 tag (上面文件的注释中有提到),解决方法我们可以先执行忽略警告的命令:
pod lib lint --allow-warnings
如果成功会出现如下输出:
-> O2View (0.0.1)
- WARN | source: Git sources should specify a tag.
O2View passed validation.
到此,我们的 O2View.podspec 就符合规范了。
在前面验证通过的基础上,我们接着执行命令:
pod repo push O2Specs O2View.podspec
执行完,如果失败会有相对应的警告和错误提示,只要按照警告和错误的详细信息进行修改和完善即可。成功的情况应该可以在终端看到类似的输出:
Validating spec
-> O2View (0.0.1)
- WARN | source: Git sources should specify a tag.
Updating the `O2Specs' repo
Already up-to-date.
Adding the spec to the `O2Specs' repo
- [Add] O2View (0.0.1)
Pushing the `O2Specs' repo
To https://github.com/marklin2012/O2Specs.git
9f32092..8d0ced5 master -> master
再进入到 .cocoapods 的目录中,可以看到已经发生了变化:
同时,我们还发现 O2Specs 的 github 仓库也已经发生了变化:
按照平时使用 CocoaPods 的习惯,我们添加依赖库之前会先搜索一下库,让我们执行一下命令:
pod search O2View
哈哈,可以看到已经建立成功了!
-> O2View (0.0.1)
Just testing
pod 'O2View', '~> 0.0.1'
- Homepage: http://aotu.io/
- Source: https://github.com/marklin2012/O2View.git
- Versions: 0.0.1 [O2Specs repo]
看到前面的搜索结果,小伙伴们是不是开始有点激动了?让我们建立一个普通的工程,命名为 TestPodDemo,然后在终端 cd 到其目录路径下,添加一个 Podfile 文件:
pod init
建立后修改 Podfile 文件内容如下:
use_frameworks!
target 'TestPodDemo' do
pod ‘O2View’
end
执行:
pod install
我们得到如下提示:
Updating local specs repositories
Analyzing dependencies
[!] Unable to find a specification for `O2View`
[!] Your Podfile has had smart quotes sanitised. To avoid issues in the future, you should not use TextEdit for editing it. If you are not using TextEdit, you should turn off smart quotes in your editor of choice.
找不到 O2View ? 额- -!。。。刚才 search 明明可以找到这个依赖库的,为什么现在找不到了呢?
别着急!其实原因是你在 Podfile 中没有指定路径,当你执行 pod install
的时候,CocoaPods 默认只会在 master 下搜索,而我们的 spec 是存在我们私有的 O2Specs 目录下的。所以解决方式很简单,就是引入搜索地址即可,在 Podfile 的顶部添加如下两行代码:
source 'https://github.com/CocoaPods/Specs.git' #官方仓库地址
source ‘https://github.com/marklin2012/O2Specs.git’ #私有仓库地址
这里必须添加两个地址,默认情况下,你如果不添加 source ,系统会默认使用官方仓库地址,但是当你添加了 source 之后,系统就不会自动搜索官方地址,所以这两句都必须添加,否则其他基于官方的依赖库都不能使用了。
再次执行 pod install
,我们就可以看到很顺利的安装成功了:
Updating local specs repositories
Analyzing dependencies
Downloading dependencies
Using O2View (0.0.1)
Generating Pods project
Integrating client project
Sending stats
Pod installation complete! There is 1 dependency from the Podfile and 1 total pod installed.
恭喜!这样一来我们就可以使用这个私有库了!
前面我们提到过,我们的这个实例依赖库 O2View 没有生成稳定的 release 版本。当我们调试完内容之后,一般都是要发布稳定版本的,更新之后再继续发布新版本。我们可以使用命令行或者在 github 页面手动生成,这里为了方便我们使用命令行,首先在终端中 cd 到之前的依赖库 O2View 的目录中,然后输入如下命令:
git tag '0.0.1'
git push --tags
git push origin master
这样我们就得到了一个稳定的 release 版本 0.0.1:
这里我用的版本号是 0.0.1 基于研发版本,关于版本号的一些规范可以参考:语义化版本 2.0.0
对于我们的 podspec 文件,我们也需要将 s.source
做一下小小的改动:
s.source = { :git => "https://github.com/marklin2012/O2View.git", :tag => version }
这样我们使用这个依赖库的时候就能对应上版本号,并且知道在 github 中使用稳定的 release 版本代码。太棒了!
最后只需要再重复 push
一下我们的 Podfile 就可以!
好了,到这里我们已经完全掌握如何创建一个本地私有的 CocoaPods 了!我们完全可以把我们项目中得代码拆出来好好的封装一些 pods, 好好使用这个黑魔法!
祝大家玩得愉快!
1、本地的私有仓库验证通过,但是远程仓库上的私有仓库验证不通过,路经不对,报Error[iOS] file patterns: The `source_files` pattern did not match any错误
解决办法:重新打开xxx.podspec文件编辑一下,确定共享文件路径没有错误,然后再上传到github上验证。
source_files文件格式有几种设置方法:
s.source_files = 'Classes/*.{h,m}' s.source_files = 'Classes/publicClass.{h,m}' s.source_files = 'Classes' s.source_files = 'Classes/**/*.{h,m}'
2、上传xxx.podspec到github和给xxx.podspec打tag顺序搞反了,验证不通过
解决办法:必须先将本地文件夹所有的文件上传到github上,然后再给xxx.podspec打上tag,打tag方式也有两种方法:
命令行方式:
git tag -m "注释" 1.0.0 git push --tags
直接在github上点击release进入创建tag:
更新时遇到此错误,处理方法。
[!] The spec did not pass validation, due to 1 error.
[!] The validator for Swift projects uses Swift 3.0 by default, if you are using a different version of swift you can use a `.swift-version` file to set the version for your Pod. For example to use Swift 2.3, run:
`echo "2.3" > .swift-version`.
遇到上面的这种情况,直接使用下面的这条命令就可以解决问题了。
echo 3.0 > .swift-version
//下面这种方法只适合于pod没有更新的情况下.
sudo gem install -n /usr/local/bin cocoapods
又出现新的错误
opening connection to trunk.cocoapods.org:443...
[!] There was an error pushing a new version to trunk: getaddrinfo: nodename nor servname provided, or not known
我的做法是重新提交了版本号,但是感觉如果不重新提交也应该没有问题的。
git tag 1.0.2
git push --tag
提到了需要进行更新:
pod repo update --verbose
[!] CocoaPods was not able to update the `master` repo. If this is an unexpected issue and persists you can inspect it running `pod repo update --verbose`
依次做完后,报上面的错误。
我的做法是重启了电脑,重新将代码提交一次,再次进行。最后成功了,但是这不能说明什么,只是我个人的情况。放在是希望对跟我遇到类似问题的人一些帮助。
pod trunk push --verbose
版权声明:本文为博主原创文章,未经博主允许不得转载。
目录(?)[+]
https://guides.cocoapods.org/syntax/podspec.html#frameworks
https://guides.cocoapods.org/syntax/podspec.html#libraries
如果branch 上的代码有了变动 ,使用方直接 pod install 或者 pod update 是不行的。
因为pod 对 branch 或者 tag 的代码在本地有缓存,需要clean缓存之后再 pod install 或 pod update
s.dependency 'FMDB', '~> 2.5' 这个 FMDB 可以是 repo master 上的库,也可以是 私有 repo 上的库。
如果是私有 repo 上的库 ,lint 时需要 指明。
lint 通过之后 push 的时候依然需要 --sources
注: xsl-mobile-cocoaspecs 是我自己创建的 私有 repo,关于如何创建私有repo 也很简单 传送门