分类
dev

Module模块化iOS开发的应用再回顾

Pre

2016年在华奥时, 在当时的项目需求下, 萌生了模块化设计的想法. 而思考如何划分各模块、各组件时, 写了篇文章: Module化的 iOS应用开发. 当时更多的是在思考划分界限, 然后用私有Cocoapods库进行组织的初实践. 而后来这个办法得到了实际使用的良好反馈, 我又将它逐步打磨. 形成了Core库(github)的设计. 可能是觉得和之前的文章内容并无实质上区别, 也就没有单独写一篇来记录. 现在想想, 其实这是前文设计的一个更完备的形式.

设计

如前文提到的, 使用私有的Cocoapods进行模块组合管理, 为了解耦关联, 这里采用Core核心库的形式:

graph TB
subgraph LYCore

  subgraph id31[Third-party Libs<br>]
  id311[AFNetworking]
  id312[LYCategory]
  id313[Realm]
  id314[...etc]
  id311---|sibling| id312
  id312---|sibling| id313
  id313---|sibling| id314
  end

  subgraph id32[Implementation<br>]
  id321[Networking Layer/API wrapper]
  id322[Persistence Layer/Database wrapper]
  id323[Configuration Layer]
  id324[Class Base]
  id321---|sibling| id322
  id322---|sibling| id323
  id323---|sibling| id324
  end

  subgraph id33[Resource<br>]
  id331[Bundle wrapper]
  id332[Image]
  id333[Font]
  id334[Sound]
  id335[...etc]
  id331---|sibling| id332
  id332---|sibling| id333
  id333---|sibling| id334
  id334---|sibling| id335
  end

end

核心库的实现中,

  • 持久化层, 数据库访问封装, 文件读写封装;
  • 配置层, 配置文件的访问封装;
  • 网络层, 包含了Server API的基础访问封装, 并可通过配置文件初始化;
  • 基类, 包含各种常用类的定义;

这样基于Core(核心)库, 可开始构建各个实际的功能模块(Module).

Module也以Cocoapods Library的形式创建, podspec里注明依赖于Core库.
构建在Core之上的Module, 可通过Core库访问Server API、了解当前用户鉴权状态、读写数据库、获取&调整配置等.
无需依赖其他模块.

App则最终以工程的形式创建, 通过Podfile选择所需的模块们(Modules).
这和使用其他的第三方库一样, 没什么区别.

整体架构大致如图:

graph TB
  id1["Module: LYCore<br>(git repo | pod lib)"]
  id11["Module: A<br>(git repo | pod lib)"]
  id12["Module: B<br>(git repo | pod lib)"]
  id13["Module: C<br>(git repo | pod lib)"]
  id14["Module: D<br>(git repo | pod lib)"]
  id15["Module: E<br>(git repo | pod lib)"]
  id21["App: 1<br>(git repo | project)"]
  id22["App: 2<br>(git repo | project)"]
  id1-->|podspec| id11
  id1 -->|podspec| id12
  id1 -->|podspec| id13
  id1 -->|podspec| id14
  id1 -->|podspec| id15
  id11 -->|podfile| id21
  id12 -->|podfile| id21
  id13 -->|podfile| id21
  id12 -->|podfile| id22
  id13 -->|podfile| id22
  id14 -->|podfile| id22
  id15 -->|podfile| id22

Author

Luo Yuluoyu@luoyu.space

分类
dev

Module化的 iOS应用开发

因工作需要,开始希望移动应用开发能走模块/组件式的过程,来提高功能的复用性,减少开发的时间,从而满足快速的产品输出需求。

需求的来源源自公司的新项目方向通常是与已有的项目存在部分类似的功能,又有自己独特的模块。

在此基础下,将功能尽量独立出来,做到不同项目导入+配置即可使用,除了减少开发、测试的工作,也可提高该功能的可维护性(修改一次代码,可以同时更新多个引用此功能的项目)。

难点在于模块式的iOS应用开发。

首先是解耦功能。

实际情况1

考虑到网络层一般已有AFNetworking/Alamofire这样的库,网络层通常是对应Server RESTAPI进行配合,做初步解析,区分API Error与Success,以便每个数据请求处理结果。

对于某些特定的情况,例如没有对OSS文件服务器接口进行包装的Server,文件上传的操作也是在App内做的情况下,这些操作也应该归纳到网络层的范围内。

这样下来,如果在Server Domain,API前缀,OSS鉴权信息等可配置的情况下,可以将该组件+网络库(如AFNetworking)独立出来,形成一个模块。

实际情况2

用户登录

包含用户的权限判定,与登录界面显示的触发;登录界面UI与输入交互;登录操作的网络请求,成功失败的处理等。

权限判断与界面触发都与其他界面里用户的操作相关联,但可行的是,判断本身都是与固有数据的操作,是外部对模块内的单向调用。

登录界面UI,无法确定,同一家公司的话,可能有一定的复用性,具体情况待定。

网络请求可以暴露出组件,或是可配置的请求地址,待定。

可见登录,是一个有部分独立性的模块。

实际情况3

注册

注册UI,无法确定,不同项目有不同的注册所需字段的需求;
注册步骤,无法确定,不同项目,注册的流程都可能不一样,有的追求简单快速,有的则有许些必要的信息需要录入并验证。

注册不应该做成模块,可复用性也很低。

模块与项目引用的解决方案

首先,应该考虑的是Git与Git Submodule,似乎生来就是为项目模块化设定的。

好处有很多,依赖关系很明确,所见即所得,如何将模块添加到工程都是开发人员自己决定的。

而对于工程本身来说,其实还是一个整体。

编译输出全在一个二进制文件里。

其次,使用私有的Cocoapods进行配置管理。

思路大致如下: