创建自己的本地私有pod(实践)
序
下面描述到的操作,我全部都一一实践过,可以保证是没有问题的。如果有读者已经完成了部分操作,可以根据需要选择步骤阅读或者查看“遇到的问题”栏。写了好长时间,如果对你有帮助,还望给点个赞,非要捐助的我也没意见~~~
为什么要这么干
开发过程中我们会有许多公用的组件,比如多个工程会同时引用一段代码。记得多年之前,我曾经打过静态包,还制作过framework来满足我的需求,但是都太不方便了。尤其是多人合作开发的时候,弊端很大。把公用库交给cocoapods来管理,是我觉得目前最方便的解决方案了。伙伴们只要简单几句命令行就可以完成库的安装和更新,真乃团队协作利器。
操作过程中如果遇到命令不明的情况,建议多去官网搜索,里面提供的内容都是最全最准的。Command-line Reference
准备工作
1、准备一个git远程仓库,存放我们自己的specs。
specs可以理解为我们查找库时候的一个索引,为什么我们执行pod search AFNetworking命令时,返回结果如此之快。因为安装cocospod的时候,本地目录就已经有了一份master(公开)的specs,全球程序员们提交到cocospod的开源代码在这都有记录。
我们可以通过执行命令1
查看下目录结构,结果一目了然。
命令1
open ~/.cocoapods/repos/master
2、一个git远程仓库,存放我们自己的公共组件代码。
其实这个也可以是别的(比如svn),不过我只尝试过git。git远程仓库我用的是偏爱的coding,免费、好使。
创建私有Spec
准备工作的第一步已经完成了,我创建的私有specs仓库地址为https://coding.net/zanyfly/ZYSpecs.git。下面执行命令2
把Spec创建到本地。
命令2
pod repo add ZYSpecs https://coding.net/zanyfly/ZYSpecs.git
这时候ZYSpecs就在本地目录下创建成功了,通过命令查看ZYSpecs的目录结构,会发现里面的内容和git仓库上的保持一致。
open ~/.cocoapods/repos/ZYSpecs
创建个人pod
这一步的主要目的是为我们的公用代码创建podspec文件,这个文件会要求我们配置很多必要的信息。如果你的公用库代码已经是一套成型的组织,那么可以考虑直接新建一个podspec。我的做法是利用命令3
创建一个完整的pod,也就是从头开始,好处是可以选择生成Example工程和测试框架,方便调试以及帮助他人学习使用。
1、创建podspec
命令3
pod lib create ZYLib
过程中终端会向我们提出一系列问题,包括开发语言是OC还是Swift(Objective-C or Swift
),demo程序(Making a Demo Application),是否包含测试框架(Choosing a Test Framework),界面测试等(View-based Testing)。选项问题都很简单,我选择了包含demo程序,没有测试框架,大家可以根据自己的实际需要进行选择。</br>
2、编辑podspec
操作成功后,可以看到ZYLIB.podspec文件就已经创建好了,而且其中包含一个Example目录。大体的结构图(摘自官网)
$ tree ZYLIB -L 2
ZYLIB
├── _Pods.xcproject
├── Example
│ ├── ZYLIB
│ ├── ZYLIB.xcodeproj
│ ├── ZYLIB.xcworkspace
│ ├── Podfile
│ ├── Podfile.lock
│ ├── Pods
│ └── Tests
├── LICENSE
├── ZYLIB.podspec
├── Pod
│ ├── Assets
│ └── Classes
│ └── RemoveMe.[Objective-C/m]
└── README.md
用编辑器打开podspec,把里面的资料都填写一下,下面是我写的(#注释的部分都被我删掉了)。特别指出:务必保证填写的每一项都要是正确的,比如主页和链接都要能够访问。
Pod::Spec.new do |s|
s.name = 'ZY_LIB'
s.version = '0.1.0'
s.summary = 'This is my pod lib'
s.description = <<-DESC
TODO: Add long description of the pod here.
DESC
s.homepage = 'https://git.coding.net/ivanzeng/ZY_LIB.git'
s.license = { :type => 'MIT', :file => 'LICENSE' }
s.author = { 'zengyuan' => 'zanyfly@126.com' }
s.source = { :git => 'https://git.coding.net/ivanzeng/ZY_LIB.git', :tag => s.version.to_s }
s.social_media_url = 'http://www.jianshu.com/users/f8e79006b5c6/latest_articles'
s.ios.deployment_target = '7.0'
s.source_files = 'ZY_LIB/Classes/**/*'
s.public_header_files = 'ZY_LIB/Classes/**/*.h'
s.dependency 'AFNetworking', '~> 2.0'
end
提示: s.public_header_files
是要公开的头文件,s.dependency
表示依赖库,我的库HTTP通信部分用了AFNetworking,没有的话可以直接注释掉。</br>
3、测试podspec
我首先是打开Example,在工程里直接尝试调用库文件,保证编译过程中没有错误,没有警告,运行过程中可以正常使用。
最后打开命令行,cd到podspec所在的当前目录,执行命令4进行检验。
命令4
pod lib lint
幸运的话,我们可以看到passed validation.的提示。如果提示验证失败,不要着急,仔细阅读它描述的错误信息,基本上google一下就能找出解决方案。</br>
备注:要是实在是解决不了警告也没关系,在后面追加 --allow-warnings
4、提交ZY_LIB代码
这时候ZY_LIB验证通过,确定没问题了,那么把代码push到我们公用库远程仓库上去,否则其他的同事或者合作者就没法用了。基本操作就是add、commit、push,最后重点说明一个事情,push结束以后千万不能忘记打tag!!!而且tag值一定要和s.version保持一致!!!
$ git tag -m "ZYLib say hi to you" 0.1.0
$ git push --tags
这些操作全都结束以后,可以通过log日志的方式,来确保我们没有遗漏操作。</br>
5、push podspec
执行命令5,这时候本地的repos目录就有ZYSPECS
了,和~/.cocoapods
下的master
是同级。
命令5
pod repo push ZYSPECS ZYLIB.podspec。
提交时候,会再进行一次验证,如果遇到警告不通过的问题,可以考虑 pod repo push ZYSPECS ZYLIB.podspec --allow-warnings。
</br>
6、搜索公用库,执行命令6
命令6
pod search ZYLib
查询到结果,说明已经安装成功。
使用公用库
使用方式和其他的开源库一样,修改podfile,增加库标记。不同的是,需要在头部增加
source 'https://github.com/CocoaPods/Specs.git'
source 'https://git.coding.net/ivanzeng/ZYSpecs.git'
否则可能会出现无法正确安装的情况。其他同事或者小伙伴,在自己的电脑执行一下命名进行安装,
pod repo add ZYSpecs https://git.coding.net/ivanzeng/ZYSpecs.git
如果是更新就换成 repo update。
遇到的问题
1.demo下无法import到库头文件
解决办法:我遇到过一次,如果发生了,手动打开pod工程 - Build Phases - Headers - Public,把我们需要的头文件加进去。
2.pod lib lint执行报错
记得修改下summary,别用初始的。看看source和homepage是否正确,public_header_files是否正确引用。还要记住代码文件不能有警告,有警告也无法编译成功。
3、 pod lib lint执行报错
- ERROR | [iOS] xcodebuild: Returned an unsuccessful exit code. You can use `--verbose` for more information.
- ERROR | xcodebuild: ....
- error: include of non-modular header inside framework module '' [-Werror,-Wnon-modular-include-in-framework-module]
...
原因就是我的库的某个头文件中直接import了第三方库(我对它有依赖)的头文件,我采用了前向声明的方式解决。
4、pod lib lint验证成功了,但是在接下来的pod repo push报错
而且报的是就是podspec无法通过验证,解决方法,重新提交一个tag并push。在执行pod repo push,验证通过。
5、pod search可以成功的搜索到我们的库,但是在项目中执行pod install报错
Unable to find a specification for **
在podfile 文件中
source 'https://github.com/CocoaPods/Specs.git'
source 'https://git.coding.net/ivanzeng/ZYSpecs.git'
6、在pod中引入第三方库报错
比如在自己的pod中引入sharesdk,lint时报错
The 'Pods-Your Example' target has transitive dependencies that include static binaries:
这是因为sharesdk以framework形式出现,导致lint在执行的时候因为静态库无法通过验证。可以在lint命令后面增加
--use-libraries
7、lint时,始终报错。Unable to interpret the specified path as a pod spec.
这个错误产生的原因我并不知道是为什么。但是确实遇到过,我的解决办法来自
https://github.com/CocoaPods/CocoaPods/issues/5195
cocospod作者的回复
I've got an open PR to cocoapods-trunk improving this. In the meantime, try running pod spec lint --verbose
执行这个命令成功了。
pod spec lint --verbose