目录
一、组件化开发
二、使用CocoaPods管理私有库
1、创建我们自己的podspec文件仓库,并连接到CocoaPods
2、创建私有库
3、编写私有库的源代码和podspec文件,并打tag
4、发布私有库的podspec文件到我们自己的podspec文件仓库
5、升级私有库
6、像三方库那样使用私有库
一、组件化开发
组件化开发是一个App最大一层的架构,使用组件化开发可以很好地完成代码解耦和并行开发。所谓代码解耦是指我们可以把项目里一些基础或具有独立功能的代码给抽离成一个一个的基础组件库或功能组件库,这样这些组件库就可以真正复用到任何一个需要使用到它们的项目里;所谓并行开发是指我们可以把项目里各业务线的项目抽离成一个一个的业务组件库,这样各业务线的项目就可以独立开发、独立打包,完全不影响其它业务线的项目、也不受其它业务线的项目影响。
组件化开发主要分四层:

- 最底层的是基础组件库
基础组件库是指那些不依赖于其它任何组件库的组件库,包括:UI库(常用间距、常用字体大小&粗细、常用颜色、常用icon、常用View)、网络库(对三方库的封装)、Util库(常用Util)、路由库(搞路由库的目的就是想让界面与界面之间互相不知道对方的存在,仅仅通过路由组件来进行跳转,从而很好地做到多业务线项目之间界面的解耦,当然同一个业务线内也可以使用路由组件来解耦界面之间的互相依赖。就像Flutter里的路由管理那样,第一步先搞个Router类,这个类里会有一个路由表的属性,我们需要把路由名和界面一一映射到这个路由表里;第二步就是搞一个类似Navigator的路由管理类,通过给它的push、pop等方法传一个路由名来打开新界面和退出新界面;第三步就是传值了,往新界面的传值可以在push方法里搞一个id类型的params,新界面返回时给上一个界面传值可以通过block的方式)。
- 往上一层的是功能组件库
功能组件库是指那些跟业务无关的、可以被多个业务线的项目复用的组件库,它们内部可能会依赖基础组件库,比如我就负责编写了项目中的:权限管理库、相机相册库、视频压缩库、原生和Flutter交互的中间容器库等功能组件库。
- 再往上一层的是业务组件库
业务组件库是指那些跟业务有关的组件库,实际开发中我们经常按模块来划业务组件库,它们内部可能依赖基础组件库和功能组件库,比如登录注册库、首页IM库、通讯录库、发现页库、个人中心库、学生答题库、老师批改库等。
- 最上一层的是宿主工程
宿主工程就像一个插座一样,你需要把哪个业务发布给用户使用,就把哪个业务组件库像个插头一样插进来就行,宿主工程本身并不负责任何业务,它就像一个平台一样来承载各个业务从而形成一款完成的App。
注意在设计和编写组件库的时候,要符合单一功能原则,即一个组件库只做一类事,一个组件只做一件事,这样可以降低组件之间的耦合性,提高组件的内聚性和健壮性。比如UI库和网络库虽然同属于基础库,但是我们得搞两个库来分别编写它们,而不要把它们塞到同一个库里,这样更上层的库就可以按需来依赖这些库了。同时要知道组件库的开发不是一蹴而就的,可以随着项目开发的深入根据实际情况逐步把一些复用性高的东西移入相应的组件库中,不要为了开发组件库而开发组件库。
二、使用CocoaPods管理私有库
接下来我们就看看在iOS开发中如何实现组件化开发。这篇文章中,会有一个名字叫做TestApp
的宿主工程,会有一个名字叫做TestSpecs
的podspec文件仓库,会有一个名字叫做TestPrivateLib
的私有库。
1、创建我们自己的podspec文件仓库,并连接到CocoaPods
打开终端,执行pod repo
命令,可见此时CocoaPods只连接了一个podspec文件仓库——它就是CocoaPods Master Repo,远程仓库的地址为https://cdn.cocoapods.org/
,本地仓库的地址为/Users/yiyi/.cocoapods/repos/trunk
。



我们还可以执行pod repo --help
命令,查看pod repo支持的其它命令。

现在我们正式开始创建我们自己的podspec文件仓库,这个仓库就是用来存放我们所有私有库、所有版本的podspec文件的。首先创建一个podspec文件远程仓库,这里取名为TestSpecs。


然后执行pod repo add podspec文件仓库名 podspec文件仓库的SSH地址或HTTPS地址
命令把我们自己的podspec文件仓库连接到CocoaPods。

而且pod repo add podspec文件仓库名 podspec文件仓库的SSH地址或HTTPS地址
命令还会自动把我们自己的podspec文件远程仓库clone下来成为一个podspec文件本地仓库。

再次输入pod repo
命令,可见此时CocoaPods就连接了两个podspec文件仓库,一个是CocoaPods官方的,一个是我们自己的。

至此,我们就创建好了我们自己的podspec文件仓库,并连接到了CocoaPods。
2、创建私有库
现在就要开始创建私有库了,这里取名为TestPrivateLib。cd到你要把私有库创建在什么目录下,这里就创建在桌面了,执行pod lib create 私有库名
命令,并根据提示选择相应的配置项,就可以创建一个私有库的本地仓库了。


创建成功后,我们桌面上就多了一个私有库TestPrivateLib的本地仓库,此时我们可以做一次“init commit”的commit操作。


接下来我们就创建一个私有库TestPrivateLib的远程仓库,关联到本地仓库,并做一次push操作。


至此,我们就创建好了私有库。
3、编写私有库的源代码和podspec文件,打tag
创建好了私有库,接下来我们就可以编写私有库的源代码了。打开示例项目的.xcworkspace文档,找到我们的私有库。


把私有库里自带的ReplaceMe.swift文件删掉。

把私有库里自带的资源文件夹和源代码文件夹添加到私有库里。

现在私有库的目录结构应该长这样。

接下来我们就可以在Class文件夹下编写源代码了,假设我们要在这个私有库里添加一个测试控制器,这里取名为TestViewController,它上面有一个UIImageView。

假设此时我们就已经完成了私有库源代码的编写,我们可能想要验证一下源代码开发得是否正确,这时就要用到示例项目了。打开示例项目的Podfile文件,可见示例项目已经默认通过本地依赖的方式依赖了我们的私有库。

cd到示例项目,执行pod install
命令来安装我们的私有库(注意:通过本地依赖时,第一次安装私有库需要执行pod install
命令,后续私有库有改动的话就不需要执行pod install
命令了,直接运行示例项目就能获取到私有库最新的代码,所以调试代码时我们经常会采用本地依赖的方式。但是如果私有库是新增了文件,那示例项目就必须得再次执行pod install
命令才能安装到最新的私有库)。

安装完成后,我们就可以在示例项目里使用一下我们私有库里的TestViewController来验证它编写得是否正确了,这里假设点击一下示例项目的ViewController就modal出私有库里的TestViewController。


源代码验证无误后,紧接着我们需要编写一下私有库的podspec文件,这里假设我们决定把此次私有库发版的版本确定为1.0.0。(podspec是pod specification的缩写,一个pod就是一个依赖库,而specification就是说明书,所以podspec翻译过来就是依赖库的说明书,用来描述某一特定版本的该依赖库)

至此,我们就编写好了私有库的源代码和podspec文件,此时我们就可以commit、push代码,并打一个1.0.0版本的tag push到远程仓库。



4、发布私有库的podspec文件到我们自己的podspec文件仓库
编写好了私有库的源代码,我们的私有库要想能像三方库那样被CocoaPods管理,就必须得把它的podspec文件发布到我们自己的podspec文件仓库,而我们自己的podspec文件仓库早已提前连接到了CocoaPods,那怎么发布呢?
cd到私有库和示例项目的上一级目录,执行pod lib lint
命令来校验一下我们的私有库。


依然是cd到私有库和示例项目的上一级目录,执行pod sepc lint
命令来校验一下我们私有库的podspec文件。


私有库和podspec文件校验通过后,依然是cd到私有库和示例项目的上一级目录,执行pod repo push podspec文件仓库名 私有库的podsepc文件名
命令来将私有库的podspec文件发布到我们自己的podspec文件仓库的本地仓库和远程仓库。


可见TestSpecs的本地仓库和远程仓库就已经都有了私有库、1.0.0版本的podspec文件。


至此,我们就发布好了1.0.0版本的私有库。
5、升级私有库
升级私有库其实就是不断重复执行3和4
1.0.0版本的TestPrivateLib,UIImageView只是一个红色的方块,现在我们开发2.0.0版本的TestPrivateLib,新增以下三个功能:
- 使得UIImageView可以显示一张本地图片(演示私有库加载资源文件)
- 使得UIImageView可以通过SDWebImage显示一张网络图片(演示私有库使用三方库)
- 私有库分离成若干个子库(演示私有库分子库)
重复执行3:编写私有库的源代码和podspec文件,打tag
功能一:使得UIImageView可以显示一张本地图片
首先我们要把图片资源都放到TestPrivateLib的Assets目录下。

然后修改下TestPrivateLib podspec文件里的资源文件的路径。

接着就是编写新的代码了。

编写完成后,cd到示例项目,执行一下pod install
命令安装最新的私有库,因为我们新增资源文件了,验证一下新代码是否编写有误,验证无误后,commit、push代码,就可以去开发下一个功能了。
功能二:使得UIImageView可以通过SDWebImage显示一张网络图片
修改下TestPrivateLib podspec文件,在里面添加上对三方库SDWebImge的依赖。

cd到示例项目,执行pod install
命令,帮助我们的私有库安装上三方库SDWebImage。

接着就是编写新的代码了。

编写完成后,直接运行示例项目,验证一下新代码是否编写有误,验证无误后,commit、push代码,就可以去开发下一个功能了。
功能三:私有库分离成若干个子库
我们在使用三方库的时候,可能并不会用到三方库所有的代码,可能只会用到其中的一部分,所以为了减小包的大小,我们会希望只安装其中我们需要的那部分代码。出于这个考虑,好的开源库作者都会为他们的开源库添加子库,以便我们能按需安装相应的子库。下面是AFNetworking的子库:

我们在开发私有库的时候也可以参考这种作法,把不同类型的代码放到不同的子库里,供使用者独立安装使用。假设我们的私有库里新增了View和Model文件夹,它们下面分别新增了TestView.swift
文件和TestModel.swift
文件,并且我们还创建了一个ViewController文件夹,把TestViewController.swift
文件移动到这个文件夹下了。

只分文件夹肯定是不够的,因为podsepc文件里还是指定它们是一个库。

所以我们还得在podsepc文件里真正为每个文件夹创建成子库——即把库分离为若干个子库。

编写完成后,cd到示例项目,执行一下pod install
命令安装最新的私有库,因为我们新增文件了,验证一下新代码是否编写有误,验证无误后,因为所有的功能都开发完毕了,紧接着我们需要编写一下私有库的podspec文件,这里假设我们决定把此次私有库发版的版本确定为2.0.0。

至此,我们就编写好了2.0.0版本私有库的源代码和podspec文件,此时我们就可以commit、push代码,并打一个2.0.0版本的tag push到远程仓库。



重复执行4:发布私有库的podspec文件发布到我们自己的podspec文件仓库
cd到私有库和示例项目的上一级目录,执行pod lib lint
命令来校验一下我们的私有库。


依然是cd到私有库和示例项目的上一级目录,执行pod sepc lin
t命令来校验一下我们私有库的podspec文件。


私有库和podspec文件校验通过后,依然是cd到私有库和示例项目的上一级目录,执行pod repo push podspec文件仓库名 私有库的podsepc文件名
命令来将私有库的podspec文件发布到我们自己的podspec文件仓库的本地仓库和远程仓库。


可见TestSpecs的本地仓库和远程仓库就已经都有了私有库、2.0.0版本的podspec文件。


至此,我们就升级好了2.0.0版本的私有库。
6、像三方库那样使用私有库
去TestApp项目里修改一下Podfile如下:

执行pod install
命令,还是安装到所有的文件,这是正常的,因为我们依赖的就是整个库。

但是如果我们把TestApp项目的Podfile改成只依赖TestPrivateLib的部分子库:

再次执行pod install
命令,就会只安装子库了。

完事。
网友评论