专栏名称: ScalaCool
目录
相关文章推荐
领教工坊  ·  宁高宁:跑步了 ·  21 小时前  
领教工坊  ·  宁高宁:跑步了 ·  21 小时前  
微同城本地便民  ·  古人留下的六副后悔药,人生路上须回头! ·  3 天前  
微同城本地便民  ·  古人留下的六副后悔药,人生路上须回头! ·  3 天前  
香乐坊  ·  闲人闲事——与夏天相见的日子 ·  3 天前  
香乐坊  ·  闲人闲事——与夏天相见的日子 ·  3 天前  
51好读  ›  专栏  ›  ScalaCool

用 Swift 模仿 Vue + Vuex 进行 iOS 开发(二):Coordinator

ScalaCool  · 掘金  ·  · 2018-03-18 08:22

正文

请到「今天看啥」查看全文


什么是 Coordinator

Coordinator 是 Soroush Khanlou 在 一次演讲 中提出的模式,启发自 Application Controller Pattern

先来看看传统的作法到底存在什么问题。

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
	let item = self.dataSource[indexPath.row]
	let vc = DetailViewController(item.id)
	self.navigationController.pushViewController(vc, animated: true, completion: nil)
}

再熟悉不过的场景:点击 ListViewController 中的 table 列表元素,之后跳转到具体的 DetailViewController

实现思路即在 UITableViewDelegate 的代理方法中实现两个 view 之间的跳转。

传统的耦合问题

看似很和谐。

好,现在我们的业务发展了,需要适配 iPad,交互发生了变化,我们打算使用 popover 来显示 detail 信息。

于是,代码又变成了这个样子:

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
	let item = self.dataSource[indexPath.row]
	let vc = DetailViewController(item.id)
	if (! Device.isIPad()) {
		self.navigationController.pushViewController(vc, animated: true, completion: nil)
	} else {
		var nc = UINavigationController(rootViewController: vc)
		nc.modalPresentationStyle = UIModalPresentationStyle.Popover
		var popover = nc.popoverPresentationController
		popoverContent.preferredContentSize = CGSizeMake(500, 600)
		popover.delegate = self
		popover.sourceView = self.view
		popover.sourceRect = CGRectMake(100, 100, 0, 0)
		presentViewController(nc, animated: true, completion: nil)
	}
}

很快我们感觉到不对劲,经过理性分析,发现以下问题:

  • view controller 之间高耦合
  • ListViewController 没有良好的复用性
  • 过多 if 控制流代码
  • 副作用导致难以测试

Coordinator 如何改进

显然,问题的关键在于「解耦」,看看所谓的 Coordinator 到底起到了什么作用。

先来看看 Coordinator 主要的职责:

  • 为每个 ViewController 配置一个 Coordinator 对象
  • Coordinator 负责创建配置 ViewController 以及处理视图间的跳转
  • 每个应用程序至少包含一个 Coordinator,可叫做 AppCoordinator 作为所有 Flow 的启动入口

了解了具体概念之后,我们用代码来实现一下吧。

不难看出,Coordinator 是一个简单的概念。因此,它并没有特别严格的实现标准,不同的人或 App 架构,在实现细节上也存在差别。

但主流的方式,最多是这两种:

  • 通过抽象一个 BaseViewController 来内置 Coordinator 对象
  • 通过 protocol 和 delegate 来建立 Coordinator 和 ViewController 之间的联系,前者对后者的「事件方法」进行实现

由于个人更倾向于低耦合的方案,所以接下来我们会采用第二种方案。

事实上 BaseViewController 在复杂的项目中,也未必是一种优秀的设计,不少文章采用 AOP 的思路进行过改良。







请到「今天看啥」查看全文