在 iOS 中使用 MVVM 时如何在不同部分之间进行通信
How to communicate between the different pieces when using MVVM in iOS
我做了研究,但是因为我没有足够的经验,所以我不知道在使用 MVVM 设计模式时实现 UserManger
class 通信的最佳方式是什么。
所以我的计时器应用程序已同步到云端。
到目前为止,我有 HomeViewController
、TimerViewModel
、TimerModel
、UserManager
。
UserManager
对象负责验证 User
以及将验证状态传达给其他 classes。
状态是:
.notSigned
、.signing
和 .signed
这里我需要更多的解释。 UserManager
应该向哪个对象传达更新后的身份验证状态?它属于视图控制器还是视图模型?
还有一个问题。我不知道 UserManager
是否应该只与一个 class 通信,还是可以同时与多个对象通信。
我认为大多数对象同时需要知道用户是否已签名。如果这是真的,我要实现什么样的沟通?
对于一对多,我正在考虑实现 article 中描述的 Observable 协议。如有必要,我可以复制代码而不是文章 link.
希望我描述的很好。我将不胜感激任何答案。或者关于如何通过应用程序建立对象通信的任何新见解、大局想法。你知道关于那个的任何好文章吗?
所有业务逻辑都应该在 ViewModel 中。 ViewModel 应该是调用 UserManager 中的任何方法的东西。 UserManager 应该 return 将结果解析为 ViewModel 的模型。然后 ViewModel 需要格式化数据并提醒 ViewController event/data/network 完成等
格式化数据的例子:
- 假设网络请求给您
firstName
和 lastName
。但是你只有 1 个标签来显示完整的东西。 viewModel 应该将这些字符串加在一起(使用 space)并向 VC. 提供 fullName
属性
- 如果你取回了一个 Double,但需要将其格式化为货币并显示一个符号。
- 获取时间戳并格式化为日期字符串。
这些是 ViewModel 应该做的事情。这样它们就可以独立于 UI 代码和生命周期进行测试。
通讯:
您可以使用标准的 Apple API 设计并创建一个带有委托和回调的 ViewModel
协议。每个 VM 都会确认协议,VC 会将自己设置为其 VM 的委托,并且 运行 您的代码在 VC 的委托回调函数中。
命名:
单词 "Manager" 已失宠,因为它通常是在 class 的用法不明确时使用的默认单词。出于这个原因,它有上千种不同的定义。负责发出网络请求and/or 存储状态的 class 应称为 "Service"。即 "UserService".
分享状态:
我可能会对这一点感到愤怒。但是当状态需要在多个 VC、组件、VM 等之间共享时。我遵循 Angular 设置的设计模式/架构。我将我的服务设为 classes 单例。让他们存储状态。然后每个 ViewModel 的每一项都有一个真实来源,并且可以随意格式化。
其他人使用 RxSwift 等框架并使用 Observables 和类似技术。我个人的看法是,这是一种巨大的矫枉过正,涉及巨大的学习曲线,意味着添加大量的大库并给项目带来很大的风险。我更喜欢坚持已经可用并在 eco-system 中工作的模式,并保持简单。
编辑:one-to-many:
这可能取决于您的用例和架构决策。我发现在我的大多数用例中可以避免 one-to-many 问题,方法是让单例存储状态并让 VC 在每次调用 [=14 时触发 ViewModel 中的某些内容=].每次打开 VC 时,它都会获取最新数据并继续。我提出避免使用 one-to-many 的原因是在大多数情况下屏幕上只有 1 个 VC 并且在任何时间点都只有 运行ning 代码(使用 childViewControllers 是例外)。我发现完全回避这个问题并通过改变我与数据交互的方式来保持应用程序简单是可能的,而不是改变苹果的结构 APIs.
现在,根据您的使用情况,如果您有多个计时器和大量屏幕切换,这可能不起作用,可能会错过一个事件。
NotificationCenter 不是我最喜欢的方法,但如果我遇到无法避免的 one-to-many 情况,我会试一试。正如文章中提到的,您可以通过这种方式访问 swift 功能的一些缺点。它至少有一个额外的好处,那就是它已经存在了很长时间并且被很好地理解并且不太可能改变太多。如果其他开发人员正在开发此应用程序,则不会有任何巨大的学习曲线。
文章中提到的另一种方法很有趣,构建您自己的精简版 RxSwift 以将观察者添加到项目中。我目前使用 RxSwift 的问题是当人们不将它与单例或某种中心控制点结合使用时。当你在对象 A 上有一个被 B 观察到的 Observable 时,它也有另一个被 C 观察到的 Observable,它调用 D 上的一个函数,这个函数被 E、F 和 G .... 等等。这种代码风格极其混乱、难以阅读、容易出错且难以调试。只要避免这种情况,并且它是具有可观察对象的单例并且所有 ViewModel 都在观察,我认为如果您愿意付出努力来构建和维护它,这样的事情就可以了。
我做了研究,但是因为我没有足够的经验,所以我不知道在使用 MVVM 设计模式时实现 UserManger
class 通信的最佳方式是什么。
所以我的计时器应用程序已同步到云端。
到目前为止,我有 HomeViewController
、TimerViewModel
、TimerModel
、UserManager
。
UserManager
对象负责验证 User
以及将验证状态传达给其他 classes。
状态是:
.notSigned
、.signing
和 .signed
这里我需要更多的解释。 UserManager
应该向哪个对象传达更新后的身份验证状态?它属于视图控制器还是视图模型?
还有一个问题。我不知道 UserManager
是否应该只与一个 class 通信,还是可以同时与多个对象通信。
我认为大多数对象同时需要知道用户是否已签名。如果这是真的,我要实现什么样的沟通?
对于一对多,我正在考虑实现 article 中描述的 Observable 协议。如有必要,我可以复制代码而不是文章 link.
希望我描述的很好。我将不胜感激任何答案。或者关于如何通过应用程序建立对象通信的任何新见解、大局想法。你知道关于那个的任何好文章吗?
所有业务逻辑都应该在 ViewModel 中。 ViewModel 应该是调用 UserManager 中的任何方法的东西。 UserManager 应该 return 将结果解析为 ViewModel 的模型。然后 ViewModel 需要格式化数据并提醒 ViewController event/data/network 完成等
格式化数据的例子:
- 假设网络请求给您
firstName
和lastName
。但是你只有 1 个标签来显示完整的东西。 viewModel 应该将这些字符串加在一起(使用 space)并向 VC. 提供 - 如果你取回了一个 Double,但需要将其格式化为货币并显示一个符号。
- 获取时间戳并格式化为日期字符串。
fullName
属性
这些是 ViewModel 应该做的事情。这样它们就可以独立于 UI 代码和生命周期进行测试。
通讯:
您可以使用标准的 Apple API 设计并创建一个带有委托和回调的 ViewModel
协议。每个 VM 都会确认协议,VC 会将自己设置为其 VM 的委托,并且 运行 您的代码在 VC 的委托回调函数中。
命名:
单词 "Manager" 已失宠,因为它通常是在 class 的用法不明确时使用的默认单词。出于这个原因,它有上千种不同的定义。负责发出网络请求and/or 存储状态的 class 应称为 "Service"。即 "UserService".
分享状态:
我可能会对这一点感到愤怒。但是当状态需要在多个 VC、组件、VM 等之间共享时。我遵循 Angular 设置的设计模式/架构。我将我的服务设为 classes 单例。让他们存储状态。然后每个 ViewModel 的每一项都有一个真实来源,并且可以随意格式化。
其他人使用 RxSwift 等框架并使用 Observables 和类似技术。我个人的看法是,这是一种巨大的矫枉过正,涉及巨大的学习曲线,意味着添加大量的大库并给项目带来很大的风险。我更喜欢坚持已经可用并在 eco-system 中工作的模式,并保持简单。
编辑:one-to-many:
这可能取决于您的用例和架构决策。我发现在我的大多数用例中可以避免 one-to-many 问题,方法是让单例存储状态并让 VC 在每次调用 [=14 时触发 ViewModel 中的某些内容=].每次打开 VC 时,它都会获取最新数据并继续。我提出避免使用 one-to-many 的原因是在大多数情况下屏幕上只有 1 个 VC 并且在任何时间点都只有 运行ning 代码(使用 childViewControllers 是例外)。我发现完全回避这个问题并通过改变我与数据交互的方式来保持应用程序简单是可能的,而不是改变苹果的结构 APIs.
现在,根据您的使用情况,如果您有多个计时器和大量屏幕切换,这可能不起作用,可能会错过一个事件。
NotificationCenter 不是我最喜欢的方法,但如果我遇到无法避免的 one-to-many 情况,我会试一试。正如文章中提到的,您可以通过这种方式访问 swift 功能的一些缺点。它至少有一个额外的好处,那就是它已经存在了很长时间并且被很好地理解并且不太可能改变太多。如果其他开发人员正在开发此应用程序,则不会有任何巨大的学习曲线。
文章中提到的另一种方法很有趣,构建您自己的精简版 RxSwift 以将观察者添加到项目中。我目前使用 RxSwift 的问题是当人们不将它与单例或某种中心控制点结合使用时。当你在对象 A 上有一个被 B 观察到的 Observable 时,它也有另一个被 C 观察到的 Observable,它调用 D 上的一个函数,这个函数被 E、F 和 G .... 等等。这种代码风格极其混乱、难以阅读、容易出错且难以调试。只要避免这种情况,并且它是具有可观察对象的单例并且所有 ViewModel 都在观察,我认为如果您愿意付出努力来构建和维护它,这样的事情就可以了。