写在开始:这是一篇小白创建Pod私有库的采坑笔记,本文假设读者已经装好了cocoapods工具,而且了解pod的基本操作。
第一步:拆分相关代码
最近尝试着做公司项目的组件化,最先开刀的是网络模块。我们的网络请求模块是基于AFNetWorking封装的,看着代码量不多,但是代码里面的耦合比较严重,没有很好的遵循面向对象设计的六大设计原则。我在拆分代码时还是有点小挣扎。。。好了,废话少说,开始正题。创建私有库的第一步就是,将你想要独立出来模块的代码先从项目中抽离出来。这一步可以说是“好的开始是成功的一半”的最好写照了。关于这一部分,没有太多的建议,只能具体问题具体分析;但是理论指导可以从六大设计原则中获得:
- 单一职责原则
- 迪米特法则(最少知道原则)
- 依赖倒置原则
这三个原则是我感觉在拆分代码时参照比较多的。一般网络模块都可能会依赖其他的第三方库,这需要我们评估,如果是依赖的比较重量型的库的话,而且只是使用了该库的一两个小功能(非核心功能)。那么我们是不是应该在自己的网络模块实现这些小功能或者方法,减少不必要的依赖。虽然代码会有一点冗余,但是对模块本身的减重有很大好处的话,还是值得考虑的。还有一点就是,必须分清楚项目中关于网络这块的代码,哪些是业务逻辑相关的,哪些是网络模块必须的,通用的东西。只有弄清楚了这些,才能做到有的放矢的拆分代码。如果是不依赖其他第三方库的基础模块的话,将你拆分出来的代码放到一个新建的Xcode项目中编译不报错;或者是有依赖第三方库,将代码放到只添加了依赖库的新建Xcode项目中编译不报错;这就是第一步拆分代码成功的标志。
第二步:Github上新建代码仓库和私有库仓库
上面一步做好之后,接下来才是cocoapods相关的操作。这里先说一下操作逻辑:我们要创建两个git仓库,一个存放私有库的项目代码;另一个存放我们所有私有库的.podspec文件(即描述文件),以后所有的私有库.podspec文件都将存放在这个仓库里。这里创建仓库的时候,readme,gitignore,license文件都可以先不创建。比如我创建了MNetWorking原始代码仓库(以Github为例):
和YkzPrivatePodSpec私有库配置文件仓库:
然后我们在本地创建对应的私有库仓库,用终端输入以下命令进入pod的仓库列表:
cd ~/.cocoapods/repos
接着输入以下命令创建本地仓库,并同前面创建的私有库配置文件仓库关联起来:
pod repo add YkzPrivatePodSpec https://github.com/zrx89757/YkzPrivatePodSpec.git
输入ls可以看到当前的所有本地仓库
第三步:创建私有库项目
本地和远程的私有库配置文件仓库都创建好了,远程的私有库项目代码仓库也创建好了,接下来创建本地的私有库项目。cd到你喜欢的路径,执行以下命令创建自带Pod的Xcode项目:
pod lib create MNetWorking
命令运行完之后会让你输入一些参数比如:在哪个平台使用,什么开发语言,是否带有示例demo,使用哪个测试框架等等。
即使你选择不需要示例demo,创建出来的项目里面还是会有Example文件夹,而且自带了LICENSE和README和gitignore文件,文件结构如下:
在跟Example同级的MNetWorking里面有两个文件夹:
Assets:存放图片资源等
Classes:存放源码,创建时自带一个ReplaceMe.m文件
第四步:配置私有库
我们将第一步拆分出来的代码放到Classes文件夹下面即可。然后编辑.podspec文件,可以用vi或者vim,也可以直接用Xcode编辑。如下图:
除了最后一行依赖设置以外,其他的都可以使用默认值。如果你准备创建的私有库需要依赖第三方的话,就在最下面那里写明需要依赖的第三方库。当然你的私有库也可以依赖别人的私有库。关于依赖库的版本需要特别说明一下,我的建议是尽量不要像我截图中那样指定精确的版本,否则当出现以下情况时,你创建的私有库无法在主工程中使用:你的主工程使用了A库,而且podfile文件中指定了精确版本;而你的私有库也依赖了A库,指定了跟主工程一样的版本。当后面由于某些原因你升级了主工程中A库的版本时,你发现pod install命令会报版本冲突,因为主工程和你私有库指定的依赖库A的版本不一致。你只能将你的私有库依赖升级到对应版本才能使用。所以如果你的主工程指定了A库的版本2.2.0,你的私有库也需要依赖A库,那么最好写成>= 2.2.0
的样式。
第五步:验证私有库
接下来就可以验证私有库了,如果你没有依赖第三方库或者依赖的都是公有的第三方库,在.podspec所在的层级运行pod lib lint --allow-warnings
命令,其中'--allow-warnings'是忽略警告的意思;如果依赖了私有库,需要加上source,即pod lib lint --sources=https://github.com/mafeng-Bryant/Specs.git,https://github.com/CocoaPods/Specs.git --allow-warnings
,前面是你依赖的私有库地址,后面是pod的官方公有库地址。验证成功的界面如下:
第六步:提交到远程仓库
成功以后就可以进入Example目录,执行pod install
命令。如果你依赖了私有库,podfile中需要添加上面提到的对应的source。install成功以后我们的私有库就算是创建好了。接下来将我们的项目代码提交到远程仓库:
git remote add origin https://github.com/zrx89757/MNetWorking.git
git add .
git commit -m "init spec"
git push origin master
//注意:如果你创建项目的时候生成了README或者license文件,那么这里你push的时候可能会push不了,这里的话可以用
git push origin master -f 强制提交,会覆盖之前的文件
第七步:打tag,推送到远程
提交成功以后,就需要给仓库打tag。tag必须跟spec文件中设置的一样:
git tag -m "version_1" 0.1.0
git push --tags
第八步:推送.podspec文件到私有仓库
最后一步,回到.podspec文件所在的层级,用以下命令将你的spec文件push到私有库进行管理:
pod repo push YkzPrivatePodSpec MNetWorking.podspec --allow-warnings
成功结果如下:
测试私有pod
新建一个项目,然后进入项目文件中,pod init
之后在podfile中写入:
source 'https://github.com/CocoaPods/Specs.git'
source 'https://github.com/zrx89757/YkzPrivatePodSpec.git'
target 'GGTest' do
# Uncomment the next line if you're using Swift or would like to use dynamic frameworks
# use_frameworks!
pod 'MNetWorking'
end
然后pod install
,成功的话就可以看到如下画面:
私有库更新
当需要更新你的私有库时,先将你的远程私有库项目代码clone到本地,然后再走一遍四,五,六,七,八的流程就好了,注意.podspec文件中的version一定要更新。
至此,关于私有库的创建和更新就说得差不多了。当然关于组件化的利弊,这完全视你们的项目和公司的业务而定,并没有统一的标准。但是经过这次实践,让我对如何写好架构,逻辑清晰的代码有了更进一步的认识。不管能不能使用到公司的项目中,有时间的话,都建议大家动手试一试!