使用 Pod 实现私有模块化管理(组件化 Pods 实现方案)

概况

众所周知组件化是个好东西,它把项目拆分成多个模块,让每个模块能够独立出来解除各个模块之间的耦合性,作为每个独立的模块不仅仅能够使用组合的方式去组建各个不同的功能组合(前提是各个组件划分的颗粒度只要足够小),而且能够独立出来运行,在开发运行以及测试中极大的提升了开发效率,让整个项目在维护上变得方便,而且整个项目的扩展性变得更健壮。

iOS 中可以通过 Pods 管理各个组件,Pods 的原理不做介绍,重点说在制作组件的方法与实践。

相信大部分项目在创建的时候,可能都没有将组件化的工程架构放入其中,因为起初的项目可能并不大,用简单的多人协作开发模式加上代码架构模式(如 MVC/MVVM/MVP 等)进行项目的开发,这样速度快,开发周期短,更符合敏捷开发的原则,所以一开始可能并没过多的去考虑组件化。但是随着项目的不断壮大,项目中不断加入新的功能,慢慢的就会发现项目的编译时间越来越长,各个功能的耦合性也变得越来越高,最为头疼的是,假如有需求要求某个功能模块抽出来单独的去集成到公司的另一个产品中,由于一开始的项目架构设计造成的代码的关联耦合,根本无法进行模块化的抽出,是不是得崩溃到哭。每一次痛苦的历程总会冲击出新的解决方案,于是组件化的搭建开始了。

使用 Pods 搭建组件的背景分两种:

1.正在开发的项目转变成组件
2.空白项目,从0到1构建组件

对于第一种,老项目迁移成组件架构模式,可以分成三步:

1.重构项目,分离出各个模块,划分清楚组件构件(可以通过使用路由思想完成组件通信的解耦)
2.抽出组件分离出主项目,将组件制作成Pods 管理的私有库,并发布模块组件版本
3.主项目使用 Pods进行各个组件的集成

第二种就相对简单点了,省去了第一种的第一步(这是个耗时耗力的过程),直接在创建整个项目的时候构建出各个组件,于是就变成了两步:

1.将组件制作成 Pods 管理的私有库,并发布模块组件版本
2.主项目使用 Pods 进行各个组件的集成

由于 Pods在创建私有库的管理时候需要绑定git实现创建,所以整个项目需要依托于 git 管理。以下的搭建是在当前项目处于 git管理中的操作。由于 github 创建私有库需要 money,所以这里我选用了其他的git托管,有很多代码托管网站可以使用,我用的是 Coding

搭建简述

Pods的搭建组件步骤如下:

1.本地创建私有的 repo 仓库(需要与远程 git 托管地址绑定)
2.创建并配置当前的 pod.spec文件
3.验证当前的.spec 的有效性
4.发布当前的 pod 版本(默认会推送到远端)

搭建详情

  • 本地创建私有的 repo 仓库
    打开 term 控制台,通过执行如下命令进行本地私有的 repo 的创建
pod repo add LCProjectSpecs https://git.coding.net/lccdl/LCModulLearnDemo.git

执行完成如下:

创建私有库

执行命令之后,我们可以打开本地的 repo 查看私有的库是否创建成功,使用如下命令:

cd ~/.cocoapods/repos

结果如下:

私有库查看
  • 创建并配置当前的 pod.spec文件
    在创建私有的 pod之前我们需要进入当前的模块所在的文件夹,然后执行如下命令进行.sepc 文件的创建
pod spec create https://git.coding.net/lccdl/LCModulLearnDemo.git

执行完成之后,当前目录下会出现一个.spec 文件,用编辑工具打开它,它是一个ruby格式的文件配置可以按照如 下进行配置

Pod::Spec.new do |s|

  s.name         = "LCModulOne"   #当前的 pod 名字
  s.version      = "0.1.2"       #pod版本
  s.summary      = "测试"        #描述

  s.description  = <<-DESC
                  模块化开发
                   DESC

  s.homepage     = "https://coding.net/u/lccdl/p/LCModulLearnDemo"
  s.license      = { :type => "MIT", :file => "LICENSE" }

  s.author             = { "lccdl" => "lcc_dl@163.com" }
  s.platform     = :ios, "8.0"

  s.source       = { :git => "https://git.coding.net/lccdl/LCModulLearnDemo.git", :tag => s.version.to_s }
  s.source_files  = "LCModulOne/LCModulOne/Classes/*"
 
end
  • 验证 specs 的配置是否正确

这里可以通过两个命令来进行验证,两个命令分别针对本地与远端的验证

  pod lib lint                 #验证本地 pod 配置是否正确
  pod spec lint             #验证远端 pod 配置是否正确

这里有一个坑点,就是可能在本地验证 pod lib lint 的时候一点问题没有,但是在进行远程 pod spec lint 验证的时候会出现如下的错误提示:

image.png

这个问题可能是source_files对应的远程的路径没有填写正确造成的,本地验证的时候,source_files对应的路径的起始路径是当前路径,而source_files在远程验证时对应的目录的根目录是 git 的根目录(不是当前的 spec文件所在的目录了),所以可能在验证当前的远程的目录的时候可能会出现问题,只要把目录的路径写对就好了。

  • 发布 pod 管理的组件版本

验证成功之后,可以通过以下命令进行当前版本的发布。

 pod repo push LCModulDemoSpecs LCModulOne.podspec       #LCModulDemoSpecs 是本地的私有库  LCModulOne.podspec 当前的管理模块的 pod
pod发布

当验证 pod 配置文件没有问题之后,会将当前 pod 发布到当前的私有库LCModulDemoSpecs中,同时此时会默认推送到 gitmaster分支中(无论当前处于哪个分支下,都会推送到主分支)。这一步完成之后,我们就可以通过搜索 pods来进行正常的 pod的模块依赖了。

  • 组合不同的模块进行不同模块的开发
    一旦发布各自的模块版本之后,那么参与项目的其他的人就可以通过 pod 来加载不同的模块功能进行开发了,不过因为是私有库,所以在进行pod安装的时候,需要指定私有库的地址,使用的时候编辑 podfile,内容如下:
# Uncomment the next line to define a global platform for your project

platform :ios, '9.0'

source '[https://git.coding.net/lccdl/LCModulLearnDemo.git](https://git.coding.net/lccdl/LCModulLearnDemo.git)'

target 'LCMainRootModul' do

  # Uncomment the next line if you're using Swift or would like to use dynamic frameworks

  # use_frameworks!

  # Pods for LCMainRootModul

   pod 'LCModulOne'

end

以上说的是已有项目的使用 pod 进行组件化,如果是新开发的某个模块需要进行 pod 组件化,可以通过 pod 自带的一个命令去创建,这样创建的组件就自带 Demo 工程以及配置文件了。命令如下:

 pod lib create podTestLibrary

创建的时候会问你几个问题,直接按需要回答就好了,四个问题如下:

1.是否需要例子工程(建议保留,开发组件的时候需要用到)
2.根据需要选择一个测试类型
3.是否要基于 View 进行测试
4.类的前缀

创建完成以后,目录层级如下:

使用 pods 命令创建

开发迭代维护

在开发组件过程实际就是迭代 Pods 库的过程,我们在每个组件的实例工程中进行当前的开发,开发完成后通过发布组件的版本既可。在开发的时候由于组件在开发过程中,所以我们在开发自己的组件的时候,可以通过设置本地路径的形式去关联正在开发的组件文件,如下:

use_frameworks!

target 'LCModulOne_Example' do

  pod 'LCModulOne', :path => '../'

  target 'LCModulOne_Tests' do

    inherit! :search_paths

  end

end

当前的工程 update之后,例子工程中就有了正在开发的pod了,如下所示:

开发 pods

这里要注意,每次在往开发的 Pods 中添加文件的之后都需要通过 pod update 命令更新本地的正在开发的 Pods, 否则实例工程中可能出现找不到当前的文件。

在利用 pod 进行组件化的迁移过程中,由于在进行组件发布的时候会默认推送到当前组件所在的 gitmaster 分支,如果此时 master 分支作为线上发布版本的分支的话,我们是不希望该分支有任何的代码入侵的,响应的我们可能希望当前的pod 发布只在当前的开发环境分支进行,master 不掺杂任何开发过程中所出现的代码,为此,可以通过创建两个 git 的方案去解决这样的问题,一个 git 作为组件的开发版环境,另一个 git 专门作为发布环境只进行组件的集成与发布。如下图展示:

发布环境与开发环境处理

灵活的组件迁移组合方案

相信在进行组件化的工程项目一般都已经很庞大了,如果进行全盘迁移的话,时间上可能很长久,再者伴随的不定风险或许很大(涉及到项目的重构),所以结合之前各自项目的架构特点再去联合组件化思想对项目进行迁移是明智之举。组件化的根本目的是解耦项目各个模块间的耦合度,所以顺着这个思想,找出项目中耦合度最高的模块进行迁移才是重中之重。

其实在一般工程在起初创建的时候都已经做到了降低耦合度的构建方式,例如将一些工具类、或者通用的模块设计成项目的底层构件服务于上层模块,这些底层构件不依赖与上层模块,就已经做到了很好的降低耦合的目的,这样的设计有着层级架构的特点,所以通过层级架构+组件化构建的方式灵活的去降低项目的模块间的耦合性也是很实际化的选择,而且对比全盘迁移组件化时间维度可控性上要占据更大的优势。总之,对于不同的项目要合理的利用当前项目架构特点再去与组件化思想相结合来进行才是灵活变通的根本。

组件化Pods构想

一旦使用了 pod 构建自己的组件之后,会发现真的停不下来,正式因为组件化的构建思想,就会很自然的想到利用 Pods 去将自己工程中通用的模块做成一个组件,然后通过 git 进行管理,一旦去接受一个新的项目的时候,完全可以通过pod将需要的不同模块的东西引入到新的项目中(例如网络库的封装、基本工具类的封装、常用的宏脚本),开发效率也就得到了大大的提高,而且体现了一种前期积累后期建楼的生活哲理不是。

参考资料:

http://www.cocoachina.com/ios/20150228/11206.html
http://blog.wtlucky.com/blog/2015/02/26/create-private-podspec/
https://www.cnblogs.com/oc-bowen/p/5885476.html
https://www.zybuluo.com/qidiandasheng/note/392639

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,905评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,140评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,791评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,483评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,476评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,516评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,905评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,560评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,778评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,557评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,635评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,338评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,925评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,898评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,142评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,818评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,347评论 2 342

推荐阅读更多精彩内容

  • 项目组件化、平台化是技术公司的共同目标,越来越多的技术公司推崇使用pod管理第三方库以及私有组件,一方面使项目架构...
    swu_luo阅读 21,381评论 0 39
  • 最近在学习vue.js的时候发现,vue的组件化的思想对于编写代码是一个非常有用的事情。 首先为什么需要组件化? ...
    拂晓的云阅读 7,150评论 6 23
  • 一、安装CocoaPods 第一步:升级ruby环境 ``` sudo gem updte --system ``...
    做你的小星星阅读 5,970评论 4 18
  • 新工作的第三天,空气中弥漫着陌生与孤独,我本就是一个沉默寡言的人,再加上同事们都比我大很多,与他们的代沟更让我显得...
    Dreaming丫头阅读 175评论 1 1
  • 我想我必须要面对了,我不能让母亲对我失望。 家长会以后,我和母亲回到家里。我看到母亲很失落,但母亲什么也...
    2017々阅读 508评论 8 6