通过Cocoapods库创建私有库(各种采坑)
项目背景
最近开会说2018年项目规划,需要为各个业务部门定制app。由于我们的业务是重内容轻运营的,所以即使定制app也有很多地方是一样的,可能UI层有些不同。所以考虑把项目中一些通用的模块抽象出来,制作成pods库,供以后各个定制app使用(出于历史原因,我们项目还是使用那种把源代码的拷贝进项目的方式使用第三方库^_-)。
通过Cocoapods创建私有库
Cocoapods是神马应该不需要我介绍了,安装神马的自己网上随便找篇博文就行了,如果这都搞不定建议改行了。不过这里我想说的是,如果有过Android或者Java后台开发经验,应该知道maven这个神器(Android也可以使用gradle),也是包管理工具。maven有个中央仓库,管理包信息,就是按一定的规范把这些包组织起来,放在一个地方。请注意包本身的源代码是不在maven里的,maven去拉取包的时候,根据包在中央仓库中填写的信息,找到代码或者二进制文件地址,然后再去拉取 。Cocoapods的工作方式类似,所以如果创建私有库就需要有两个地址,第一个私有仓库地址(管理各种私有pods库,为了方便下午说明暂且叫MySpec.git),第二个是私有库源代码地址(源代码,为了方便下文说明暂且叫MyLib.git)。
在github或者一些可以提供代码托管的地方来建仓库和项目地址,我这里用的是华为云代码托管,不要问我为什么用这么烂的云服务厂商。创建地址后,我们第一步就要将我们的私有仓库添加 pod repo里,也就是让pod知道除了官方的master库以外还有我们的私有仓库。执行以下命令:
#pod repo add 仓库名 仓库名的git地址#
pod repo add MySpec https://XXX/MySpec.git
就会将我们的私有仓库添加进pod的repo列表里,具体表现是在“~/.cocoapods/repos”目录下,除了master目录外多了个 MySpec目录,后面制作的私有库的版本信息以及podspec文件都会在这个目录下。先暂且不用管这个仓库,等后面私有库制作好了之后才会用到这个仓库。说明下:执行pod repo update 命令其实就是在更新仓库里的pods库信息,由于Cocoapods官方仓包含库太多,所以为更新很久。
打开终端,在你想要创建项目的地方执行如下命令:
pod lib create MyLib
表示创建名为MyLib这个项目,中间会有各种问选择,比如使用语言是Swift还是Objc,是否创建测试工程等,各位按需选择。完了后会自动打开工程,注意我们所有要制作成的私有库的代码文件都放在当前工程目录下的一个叫classes的目录下,在里面添加完代码文件后,就要修改工程目录Mylib.podsec文件了。
#
# Be sure to run `pod lib lint NVFoundation.podspec' to ensure this is a
# valid spec before submitting.
#
# Any lines starting with a # are optional, but their use is encouraged
# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html
#
Pod::Spec.new do |s|
s.name = 'NVFoundation'
s.version = '0.1.0'
s.summary = 'A Foundation library for MyLib.'
# This description is used to generate tags and improve search results.
# * Think: What does it do? Why did you write it? What is the focus?
# * Try to keep it short, snappy and to the point.
# * Write the description between the DESC delimiters below.
# * Finally, don't worry about the indent, CocoaPods strips it!
s.description = <<-DESC
A Foundation library for MyLib, or Apps in Novax.
DESC
s.homepage = 'http://www.XXX.com'
# s.screenshots = 'www.example.com/screenshots_1', 'www.example.com/screenshots_2'
s.license = { :type => 'MIT', :file => 'LICENSE' }
s.author = { 'XXX' => 'xxx@yyy.com' }
s.source = { :git => 'https://XXX/MyLib.git', :tag => s.version.to_s }
# s.social_media_url = 'https://twitter.com/<TWITTER_USERNAME>'
s.ios.deployment_target = '8.0'
s.source_files = 'MyLib/Classes/**/*'
# s.resource_bundles = {
# 'NVFoundation' => ['MyLib/Assets/*.png']
# }
# s.public_header_files = 'Pod/Classes/**/*.h'
# s.frameworks = 'UIKit', 'MapKit'
#s.dependency 'AFNetworking', '~> 2.3'
end
每项的意思基本看英文都能明白,而且基本上不怎么需要修改。要修改是s.summary,s.description需要填写而且s.description要比s.summary长,不然后面验证podspec文件的有效性时会提示,s.homepage这个要保证能访问,不然会后面作验证的时候会提示告警。
填写完之后就表示我们的私有库代码以及配置层面的东西都完成了,现在要做的是把这个私有库放到仓库并能被引用。首先,我们要给库打标签,因为podspec文件配置的是cocoapods是根据标签的拉取代码,所以在工程目录下输入以下命令:
git add . //把修改添加进缓冲区
git commit -am "创建MyLib库" //commit
git add origin git@xxx/MyLib.git //表示添加远端git地址,这里是ssh协议的地址,不是https的
git push origin master //提交到分支
git tag -m "发布0.1.0版本" 0.1.0 //打标签
git push --tags //把标签推送带远端
接着,我们要验证下这个库的有效性,在终端里的项目目录里输入:
pod lib lint
这个时候会验证上面编写的代码文件以及podspec文件的有效性,主要是对代码做些检查比如没有实现文件,上面提到的各项填写不正确等。如果一切顺利在终端里会提示:
MyLib passed validation
如果通过后,我们就可以把这个库添加到私有仓库里了,终端里执行如下命令:
pod repo push MySepc MyLib.podspec
如果提示有告警没通过,可以在告警户后面加如下参数:
pod repo push MySepc MyLib.podspec --allow-warnings
这个命令会忽视告警,正常情况下终端会提示如下:
MyLib.podspec passed validation
这个时候在终端里输入pod search MyLib命令就搜索到该私有库了。但是通常首次是搜不到的,并会有如下提示:
Unable to find a pod with name, author, summary, or description matching
MyLib
因为cocoapods在会对库建立索引,新添加进的仓库的库是不会在索引里的,所以要更新索引。在终端里输入如下命令:
rm ~/Library/Caches/CocoaPods/search_index.json
再次执行pod search MyLib 命令就可以搜索到了。
但是到这里不要以为就完了,你在测试工程或者新建的pod工程里的podfile文件里写入pod 'MyLib', '~> 0.1.0',然后执行pod update —no-repo-update时会发现终端有如下提示:
Unable to find a specification for
MyLib (~> 0.1.0)
最开始我怀疑是不是标签没打上,改为通过如下git源文件的的方式进行引入:
pod 'MyLib', :git => 'https://XXX/MyLib.git'
发现是可以正常更新工程的,并在pods工程里看到了MyLib目录和源文件。后来查了下资料发现,这是因为默认情况,cocoapods在根据podfile构建或者更新工程的时候只会在master仓库里搜索,而不会在私有仓库进行搜索,所以需要在podfile文件里告诉cocoapods在构建或者更新工程的时候去哪里搜索库,需要在podfile文件的顶部添加如下代码:
source 'https://xxx/MySpec.git'
source 'https://github.com/CocoaPods/Specs.git'
这样就会在私有仓库以及cocoapods官方仓库进行搜索了,在pod update就正常了。