iOS工程模块化

iOS工程模块化

1. 模块化的初衷

现在的开发环境跟以前不一样了, 在全社会日积月累地进行开发后,趋向于无限多的轮子被造了出来, 而一个工程中, 混合使用的技术栈, 也变得丰富, 跨平台技术日新月异.

Native、Web、React Native、Weex、Flutter等等的框架让一个项目在什么都有一点后变得越来越脆弱.一个依赖如果同时被多个功能耦合使用, 那么它的改动将影响很大, 并且需要让依赖它的功能都进行响应的测试, 以验证修改的可用性.

要减少这些依赖导致的脆弱性, 即使这些规范是日常开发中不会随意变动的, 但难免有些赶鸭子上架的时候被开发者思考不周地进行修改的情况, 就要制定足够的规范.

同样地, 如果规范过多, 也会限制开发中的效率, 所以为了能减少这种情况, 可以回归到模块的本身来, 即对一个模块的输入与输出.

模块在遵循设计原则的基础后, 是不需要理会外部的调用情况的, 那么对于内部, 只要执行正常, 即正确的输入有正确的输出, 那么内部到底是什么, 不需要更多的关注.

但iOS工程接入很多的模块后, 可以明显感觉集成时间、编译时间的上升, 后续的还有调试艰难等问题, 这些都是模块化需要解决的问题, 而不仅仅是封装一个又一个的库.

2. 模块化的样子

很多事物只要量一大, 一些原本不需要考虑的事情都变得重要, 可能是一个项目的健壮性、可维护性, 也可能是开发调试的效率, 也可以是迭代功能的周期变长等.

综合考虑项目的模块化情况, 一个项目该拥有的模块管理相关情况包括但不限于以下几点:

  • 无耦合、易于集中管理的模块调度工具
  • 清晰的自下而上的模块调用层次
  • 易于集成、方便调试的工具

对于这几点来说, 目前的解法如下:

  • 两个解偶的依赖
    • Zouter, 有优先级的、可集中管理的解偶路由
    • Zodifier, 即时响应的、非通知的、可继承的用于登录态切换、主题切换、多语言切换等切换全局变量的属性修改器
  • 各模块的使用依赖整理后封装
  • 通过CocoaPods配置管理的插件.

3. 模块化的实践

3.1 依赖

Zouter, 是一个在CTMediator的基础上增加功能的项目依赖, 通过优先级排序和集中管理来调度所需模块.

Zodifier, 是一个属性修改器, 相关对象在初始化时配置好需要修改的属性, 在变动后, 立即生效, 摆脱了通知导致的数据不同步问题.

3.2 模块层次

各模块的层级, 按照相互关系与设计原则规划.

3.3 CocoaPods插件

CocoaPods, 是市面上大部分iOS项目使用的集成依赖的工具, 它提供可自定义的插件使用, 所以直接通过CocoaPods插件来管理这些依赖在模块化后的集成时间、编译时间、调试难题是个不错的解法.

这里记录一下开发CocoaPods插件的思路和遇到的坑.

  1. CocoaPods插件的开发调试
  2. iOS中的动态库和静态库本质
  3. CocoaPods对依赖的管理流程
  4. 模块化二进制化的思路与坑
  5. 二进制集成, 源码集成的原理

3.4 二进制模块的后台服务

因为这里的方案是将二进制的Pod放到静态服务器中, 考虑到移植性和通用性, 将静态服务器部署到OCI容器中.

由于Docker的背刺, 选择了Podman来管理镜像和容器, 但其实除了守护进程外, 没有啥区别.

3.5 总仓库

Zource是这一切的仓库, 经历了3次迭代重构, 终于可以在商用App上使用了.

该插件与美团的ZSource对比, 还欠缺集成二进制依赖时查看源码这个能力.

但已经完善了单项目单配置的能力, 每个项目, 都可以单独配置一份自己的静态私有依赖库, 无论是自己私人集成, 还是团队集成, 都能做到互不干扰.

4. 参考文章:


lZackx © 2022. All rights reserved.

Powered by Hydejack v9.1.6