iOS项目组件化实施(一)

一、 前言

随着我们游戏社区产品的功能越来越丰富,多个项目的并行开发,以及一些功能模块重复开发,严重的增加了项目的维护成本,为了提升开发效率,以及解耦合,对于一些公共的模块,保证一端开发多端使用,对项目进行组件化,便提上了改造日程,首先是对一些公共模块进行私有库组件,然后是对业务模块进行本地组件划分。

二、 如何创建一个组件

1、 创建私有化组件步骤

以登录模块组件为例 LoginModule
在终端上切换到你想要创建项目的位置 ,然后开始创建(前提条件你Mac上已经安装了cocoapod 工具)

bogon:~ hero$ cd /Users/hero/Desktop
bogon:Desktop hero$ pod lib create LoginModule

按回车后,终端会让你回答几个问题

选择项目使用平台

What platform do you want to use?? [ iOS / macOS ]

iOS

选择编程语言

What language do you want to use?? [ Swift / ObjC ]

Swift

在你的项目中是否创建一个demo工程

Would you like to include a demo application with your library? [ Yes / No ]

Yes

选择哪一个测试框架

Which testing frameworks will you use? [ Quick / None ]

None

要不要做视图测试

Would you like to do view based testing? [ Yes / No ]

Yes

至此,系统会帮你创建一个包含本地私有库的项目,新版本的cocoapod会自动执行 pod install ,模板库加载完成后,会通过命令行 打开我们刚创建的 LoginModule 工程


image1.png
2、把文件添加到私有库中

1、进入到刚创建的项目,可以看到 LoginModule 文件夹,这个文件就是用来存储,我们制作私有库时需要的代码文件和资源文件(图片、xib,以及其他资源文件)

image2.png

2、 把Class 文件内的文件进行替换


image3.png

3、 把文件加载到项目中
此时上一步加载的文件并未真正加载到项目中,此时需要在终端中进入到 Example目录中执行以下命令:

pod update --no-repo-update

在项目中可以看到我们添加的文件已经加载到工程中了


image4.png

4、加载本地化组件
在主项目中建一个专门存放本地库的文件夹,把LoginModule 组件放进去

image5.png

在Podfile文件中添加组件

image6.png

然后进行pod install ,就可以看到组件添加到项目中了

image7.png
三、制作线上私有库
1、接下来进入 LoginModule 项目打开 LoginModule.podspec 文件,删除多余的注释之后,如下:
image8.png

s.name 私有库的名字
s.version 私有库的版本:管理代码库的版本,这个是和git平台代码对应的tag版本是一一对应的
s.summary 私有库概要
s.description 描述
s.license 许可证
s.author 创建库的用户
s.source 代码在 gitLab上存储的地址,也就是远程仓库
s.ios.deployment_target 这个库最低可以安装的平台
s.source_files 存储代码文件的路径
s.resource_bundles 存储图片的路径
s.frameworks 代码中需要用到的 framework
s.dependency 依赖的第三方库

2.创建私有 Spec Repo

什么是 Spec Repo?它是所有的 Pods 的一个索引,就是一个容器,所有公开的pods都在这里面,它实际上是一个Git 仓库,remote 端在GitHub上,当我们使用 Cocoapods 后它会被 clone 到本地的 ~/.cocoapods/repos 目录下,可以看到有一个master文件件,这个就是官方的 Spec Repo 。
我们需要创建一个类似 master 的私有 Spec Repo,同理这个私有 Spec Repo也要有一个远程端,我们创建一个 Git仓库用来存储 .podspec 版本文件。如果创建私有的,需要给使用这个仓库的同事 Git仓库权限 ,我们在 Gitlab 创建仓库的名字是 HeroSpecKit ,此时,我们需要做一下关联,在终端 中执行如下命令:
命令格式# pod repo add [Private Repo Name] [GitLab HTTPS clone URL]
pod repo add HeroSpecKit Https://xxxxxxxxxxx
再次进入到~/.cocoapods/repos 目录时就可以看到 HeroSpecKit 目录了。
注意:如果有其他合作人员共同使用这个私有库 Spec Repo ,在他有对应 Git仓库权限的前提下执行相同的命令添加这个 Spec Repo 即可。

3、先在代码管理平台创建一个私有组件代码管理仓库,并把创LoginModule模块上传到远程端,我们这里是用GitLab来管理代码:

切换到 LoginModule 项目目录, 在终端执行命令:

git add .
git commit -m "第一次提交"
git remote add origin  https://xxxxxxxx
git push --set-upstream origin master

下面是提交代码后的界面


image9.png

因为 podspec 文件中获取 Git 版本控制的项目还需要 tag 号,所以需要打上一个 tag
在终端执行命令:

git tag 0.1.0
git push origin 0.1.0 

注意:0.1.0 要和 podspec 中的 s.version 版本号一一对应

4.制作远程 cocoapod 库

上一步已经把本地的代码同步到了远程仓库,并且打了 tag,此时需要把 LoginModule.podspec 推送到 [Spec Repo] 私有库
先把已经编辑好的 LoginModule.podspec 文件进行一下验证,终端切换到 LoginModule 目录,执行以下命令:

pod spec lint  LoginModule.podspec

然后,提示没有通过验证


image10.png

在命令后面 添加 --allow-warnings ,再次执行命令

pod spec lint  LoginModule.podspec --allow-warnings 

这次通过了验证


image11.png

接下来把 0.1.0 版本 LoginModule.podspec 文件推送到 [私有repod] ,在终端执行命令:
pod repo push [私有repod] LoginModule.podspec --allow-warnings
注意:如果想看到实时的进度可以在命令后面添加 参数 --verbose

image12.png

至此,已经把 LoginModule 制作组件的过程已经完成,接下来我们就可以在 主工程中使用这个组件了
在需要用到此组件的项目的 podfile 文件中添加 pod 'LoginModule' ,并在终端执行 pod install
注意:因为这是我们的私有库 ,需要在 podfile 中添加 podspec 的路径源 :
source 'http://xxxxxxxxxx' ,否则会提示找不到此库

四、组件之间的通讯问题

目前业务组件之间的通讯我们使用的是 CTMediator ,具体的可以参考 文档
https://casatwy.com/CTMediator_in_Swift.html

五、在实施组件的过程中遇到的问题
1. 图片资源加载的问题

可以参考这篇文章

https://www.jianshu.com/p/1699f537558a?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

2. xib资源加载的问题
image13.png

关于xib 的加载遇到的一些坑,xib无法被加载 ,会报如下的错误:


image14.png

从上面的错误信息,可以看到没有在bundle中找到要加载的 xib资源
这里加载xib的方式分为两种:
1、 如果在 LoginModule.podspec 添加了 s.static_framework = false ,也就是把当前的源码打包成动态库 ,此时不需要把资源加载到 Assets 资源库中,直接放到代码中即可


image.png

编译后的xib资源位置,现在项目目录中找到LoginModule_Example.app,右键进入app文件夹中, 可以看到xib资源被放到了 LoginModule.framework 库中了,如图:
image(1).png

右键找到 Framework 文件夹


image(2).png

找到 LoginModule.framework 然后右键,可以看到xib文件被打包到 framwork 包中了


image(3).png

具体的加载xib代码如下:

 let bundle = Bundle.init(for: LoginInfo.self)
 let VC = LoginInfo.init(nibName: "LoginInfo", bundle: bundle)
 view.addSubview(VC.view)

需要注意的地方:
因为xib的加载默认是从 mainbundle 中加载的,但是此时需要从指定的库中加载,所以在配置xib的时候,在 Tartget Membership 中选中 xib所属的库,同时,最后在设置一下xib所属的Module ,这样就可以正常加载 xib 了


image(4).png

image(5).png

2、 如果在 LoginModule.podspec 添加了 s.static_framework = true ,也就是把当前的源码打包成静态库,此时我们需要把 xib 添加到 Assets 资源库中才能正常使用和加载,此种情况打包后,LoginModule中的bundle资源库,会被加载到main bundle 中,如图:


image(6).png

进入到 LoginModule_Example.app 文件夹中


image(7).png

右键进入到 LoginModule.bundle 中,可以看到添加的 xib资源


image(8).png

可以看到 LoginModule.bundle,是在主 bundle中,此时加载xib的方式是从mainbundle中加载资源,代码如下:

let loginModuleBundlePath = Bundle.main.path(forResource:"LoginModule", ofType:"bundle")
let loginModuleBundle = Bundle.init(path: loginModuleBundlePath!)
let VC = LoginInfo.init(nibName: "LoginInfo", bundle: loginModuleBundle)
view.addSubview(VC.view)
3、 pod 加载提示找不到第三方库
image17.png

看了网上一些解决方案,依然无法解决问题,最终是在podfile 文件上 添加 pod 源来解决

source 'https://github.com/CocoaPods/Specs.git'

4、当把新制作的私有库添加到项目中 pod install 时 ,提示如下 错误
image18.png

根据提示执行 pod install --repo-update 命令 就可以解决问题

5、目前我们项目组件化的方案是 本地组件+远程公共组件 ,针对变化性强的业务模块作为本地组件,基础服务和稳定的非业务模块作为公共组件 ,把本地化组件转化成公共组件的过程中,有同事遇到了一个问题,因为当前组件在主工程中,同时,又制作成公共基础组件供其他项目使用,同一个文件就属于两个Git ,在提交修改完文件后,主工程提交到远程端时,就会出现新修改的文件提交不上的情况。

如图gitlab上的显示:


image19.png

解决方案:
1、假如电脑A通过 pod lib create TestPod 创建一个 TestPod项目 ,默认 TestPod 项目包含一个git 隐藏文件,为了避免出现上面的问题,先把 .git 文件删除 ,然后把它放入到主项目中,此时做一次代码提交,然后,通过终端进入到 TestPod 目录,通过 git init 初始化 一个git ,然后,把 gitLab 上的远程仓库和TestPod做关联,提交代码即可。此时,两个工程【主工程和子工程】都可以提交代码了

六、总结

组件化实施与探索,对提升我们的项目开发效率是加成的,在这期间,我们也开发了通过脚本自动发布 组件的工具,大大的提升了开发效率,在接下来一段时间会继续带着小伙伴,深入的探索架构的演变与开发效率提升的工作。

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

推荐阅读更多精彩内容