4

iOS Coordinator 实战

 3 years ago
source link: https://nemocdz.github.io/post/ios-coordinator-%E5%AE%9E%E6%88%98/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

iOS Coordinator 实战

@Nemocdz · Jun 13, 2021 · 1 min read

大部分 iOS 开发者会在 UIViewController 里编写 present/push 的代码展示另一个 UIViewController,也习惯响应关闭按钮的点击事件后调用 dismiss / pop 来关闭自身。

这样有什么问题?

  1. 难以复用:展示方式写死了,不同场景要写 if/else
  2. 灵活性低:页面展示的流程是固定的,难以插入或去掉
  3. 耦合性高:依赖了其他 UIViewController 的类信息(甚至更多)
  4. 职责不合理:UIViewController 知道被放在 navigation 或者 tab 中,也知道自己的展现形式
  5. 维护成本高:负责了这部分职责后,UIViewController 的代码会膨胀

举个简单例子:

截屏2021-06-13 下午9.43.08

CoordinatorDemo-add demo

引入一个通用的角色,负责页面转场/流程的组合和调度,这就是 Coordinator(协调者)

Coordiantor 的职责:

  • 新建和切换画面
  • 组合多个子页面为复杂界面
  • 实现页面间的回调接收/代理,转换为其他页面需要的数据

上面的例子通过引入 Coordinator 层,整体架构如下:

截屏2021-06-13 下午9.43.34

第一次重构

根据上述思想,可以给每一个 UIViewController 搭配一个对应的 Coordinator,这样重构之后,UIViewController 之间没有显式耦合,需要改动流程和展示方式时不需要修改 UIViewController 中的代码,代码变得干净和职责分明。

CoordinatorDemo-first refactor

截屏2021-06-13 下午9.44.05

第二次重构

第一次重构后,代码职责已经清楚了,基本达到架构演进的目的。接下来可以考虑怎么让代码更优雅。这里面虽然 UIViewController 之间没有显式依赖了,但是由于显式依赖了 Coordinator,其中有其他 UIViewController 的依赖,所以还存在间接依赖。解决这个问题也很简单,引入 Protocol,将 Coordinator 的结构抽象成协议,而非具体的类,这样耦合就被彻底拆开了。在不同宿主底下,可以使用不同的实现。

CoordinatorDemo-second refactor

截屏2021-06-13 下午9.44.30

第三次重构

第二次重构后,回头看看开头的几个问题

  1. 展示方式通过不同的实现解决
  2. 流程通过不同 Coordinator 连接
  3. UIViewController 之间没有耦合
  4. UIViewController 不感知自己被如何展示
  5. UIViewController 中的代码减少了

问题基本得到解决。更进一步思考在 iOS 上,还可以通过什么手段来更使 Coordinator 更强大呢?如果将 Coordinator 继承自 UIViewController,而将原来的 UIViewController 作为 CoordinatorchildController

可以获得以下特性:

  1. Coordinator 不需要由 UIViewController 持有,而是由系统管理
  2. UIViewControllerCoordinator 的依赖变成了 Delegate,可以不依赖 Coordinator 协议
  3. 可以使用 childControlleradd/remove 进行管理
  4. 能承担响应链和UITraitCollectionUIViewController 才有的特性

截屏2021-06-13 下午9.44.53

经过重构后所谓的 Coordinator 就是其实就是原来的 UIViewController,而将其展示的部分拆成了新的 childController 专门用于视图展示和处理(在有些文章中也被称为 FlowController)。

CoordinatorDemo-third refactor

项目中可以根据需要进行演进,第一次重构已经能实现拆分的思想,第二次重构增加了灵活性,第三次重构依赖了 iOS 目前已有的 API,在架构上反而不是一件太好的事情,因为不同的系统能力不一定对齐,甚至在同系统上(比如引入 FlutterSwiftUI 后)也不一定能够长久使用。

漫谈 iOS 架构:从 MVC 到 VIPER,以及 Redux | Nelson

Coordinator and FlowController


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK