ios - 在iOS中使用MVVM时如何在不同片段之间进行通信

标签 ios swift mvvm viewmodel

我做了研究,但是由于没有足够的经验,我不知道在使用MVVM设计模式时实现UserManger类通信的最佳方法是什么。

因此,我的计时器应用已同步到云端。
到目前为止,我正在使用HomeViewControllerTimerViewModelTimerModelUserManager
UserManager对象负责对User进行身份验证,并将身份验证状态传达给其他类。

状态为:.notSigned.signing.signed
在这里,我需要更多的解释。 UserManager应该向哪个对象传达更新的身份验证状态?它由 View Controller 或 View 模型拥有吗?

还有一个问题。我不知道UserManager是否假设只与一个类进行通信,还是可以同时与许多对象通信。
我认为大多数对象同时需要知道用户是否已签名。如果是这样,我应该进行哪种沟通?

对于很多人,我正在考虑实现此article中描述的Observable协议(protocol)。如有必要,我可以复制代码而不是文章链接。

我希望我描述得很好。我将不胜感激。或任何有关如何通过应用程序设置对象通信的新见解,大概念。您知道关于这方面的好文章吗?

最佳答案

所有业务逻辑都应在ViewModel内部。 ViewModel应该是调用UserManager内部任何方法的事物。 UserManager应该将解析为模型的结果返回给ViewModel。然后,ViewModel需要格式化数据并提醒ViewController事件/数据/网络完成等。

格式化数据的示例:

  • 可以说网络请求为您提供了firstNamelastName。但是您只有1个标签来显示完整的内容。 viewModel应该将这些字符串加在一起(带有空格),并为VC提供fullName属性。
  • 如果返回Double,但需要将其格式化为货币并显示符号。
  • 获取时间戳并格式化为日期字符串。

  • 这些是ViewModel应该做的事情。这样就可以独立于UI代码和生命周期进行测试。

    通讯:

    您可以使用标准的Apple API设计并创建带有委托(delegate)和回调的ViewModel协议(protocol)。每个VM都会确认协议(protocol),VC将自己设置为其VM的委托(delegate),并在VC的委托(delegate)回调函数中运行您的代码。

    命名:

    单词“Manager”已不再受欢迎,因为在不清楚类的使用时,它通常是默认单词。因此,它具有一千种不同的定义。负责发出网络请求和/或存储状态的类应称为“服务”。即“UserService”。

    共享状态:

    我可能会让很多人对此感到愤怒。但是当需要在多个VC,组件,VM等之间共享状态时,我将遵循Angular设置的设计模式/体系结构。我使我的服务类(class)单例。让他们存储状态。然后,每个ViewModel的每个项目都有一个事实来源,可以随意设置其格式。

    其他人使用RxSwift之类的框架,并使用Observables和类似技术。我个人的观点是,这是巨大的矫over过正,涉及巨大的学习曲线,意味着要添加大量的大型图书馆,并给项目带来很大的风险。我更喜欢坚持现有的模式并在生态系统中工作,并使事情保持简单。

    编辑:一对多:

    它可能取决于您的用例和体系结构决策。我发现在大多数用例中,通过让单例存储状态并让VC在每次调用viewDidAppear时在ViewModel中触发某些事情,可以避免一对多的问题。每次打开VC时,它都会获取最新数据并继续运行。我之所以避免一对多的原因是,在大多数情况下,屏幕上只有1个VC,并且在任何时间点都运行代码(使用childViewControllers是异常(exception))。我发现可以通过改变我与数据的交互方式而不是更改Apple API的结构来完全避开此问题,并使应用程序保持简单。

    现在,根据您的用例,如果您有多个计时器和大量的屏幕切换功能,则可能无法正常工作,因此有可能错过事件。

    NotificationCenter不是我最喜欢的方法,但是如果遇到无法避免的一对多情况,我会尝试一下。如本文所述,存在一些缺点,您可以通过这种方式使用快速功能。它至少具有一个已经存在了很长一段时间并且广为人知并且不太可能改变太多的优点。如果其他开发人员正在开发此应用程序,则不会有任何巨大的学习曲线。

    本文中提到的另一种方法很有趣,它构建了自己的精简版RxSwift,以将Observers添加到项目中。对于RxSwift而言,我目前的问题是人们不将其与单例或某种中央控制点结合使用。当您在对象A上有一个Observable时,B的Observed也会有另一个C的Observable的Observable,后者调用D上的一个函数,该函数由E,F和G ....依此类推。这种代码风格令人难以置信,凌乱,难以阅读,容易出错且难以调试。只要避免这种情况,并且它具有可观察的并且所有ViewModels都处于观察状态的单例,我认为,如果您愿意努力构建和维护它,那么类似的事情就可以了。

    关于ios - 在iOS中使用MVVM时如何在不同片段之间进行通信,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56357192/

    相关文章:

    ios - 以编程方式添加自定义 UIButton fatal error

    ios - 更新 TableView 单元格数据

    swift - 如果一个键在数组中重复,我想添加该键的值

    c# - 如何将转换器应用于 ObservableCollection 的每个项目?

    ios - 如何在编辑模式下调整 UITableViewCell 背景的大小

    ios - 当 segue 为模态时 performSegueWithIdentifier 非常慢

    android - 如何使用 SingleLiveEvent 类将多个命令从 MVVM 发送到 View

    c# - 这个单向绑定(bind)会泄漏内存吗?

    ios - 在某个区域创建一个随机的 CLLocation 坐标

    ios - Xcode 7.1 中没有 "Run in Full Simulator"的 UIView 动画?