【问题标题】:Adopting MVVM in iOS: ViewModel responsibilities?在 iOS 中采用 MVVM:ViewModel 的职责?
【发布时间】:2017-02-25 13:10:47
【问题描述】:

我想在我的下一个 iOS 项目中应用MVVM 模式,我已经阅读了一些关于它的帖子和博客。但他们展示的示例非常简单,没有业务逻辑,只有数据模型实体和ViewModel 更新。我不清楚谁实际上负责管理业务逻辑和操作:应该是ViewModel 还是Model

例如,假设我的一项功能需要:

  • 向 Web 服务请求一些数据
  • 解析此类数据并将其映射到我的数据模型实体
  • 对此类实体执行一些检查和操作,并使用结果更新ViewModel
  • 处理触发更多更新和操作的计时器

为了实现MVVM,我应该如何分配这些职责?

【问题讨论】:

    标签: ios mvvm model viewmodel encapsulation


    【解决方案1】:

    从 MVVM 中的数据流我们可以看到 ViewModel 的职责:

    Data Flow in MVVM
    1. UI calls method from ViewModel (Presenter).
    2. ViewModel executes Use Case.
    3. Use Case combines data from User and Repositories.
    4. Each Repository returns data from a Remote Data (Network), Persistent DB Storage Source or In-memory Data (Remote or Cached).
    5. Information flows back to the UI where we display the list of items.
    

    更多关于 MVVM 的描述可以在这里:https://tech.olx.com/clean-architecture-and-mvvm-on-ios-c9d167d9f5b3

    【讨论】:

      【解决方案2】:

      假设有一个获取 cmets 的 Web 服务

      您可以创建 CommentService 负责下载数据、解析和初始化/更新模型。因为我们需要获取cmets,所以有一个方法

      func getComments(_ completion: () -> [Comment])
      

      CommentService.getComments 由 ViewModel 在其加载方法中调用。

      class ViewModel {
        private let commentService: CommentService
        private var comments: [Comment] 
        ...
      
       func load() {
         commentService.getComments() { [weak self] comments in
            self?.comments = comments 
            //notify somehow the view..for example by using delegate
         }
       }
      }
      

      例如,我们想要对 cme​​ts 投反对票/赞成票,所以我们可以实现它

      struct CommentService {
      
        ...
      
        func upvote(comment: Comment, completion: (Void) -> (Comment)) { 
      
          if comment.upvoted {
             //throw error
          }
           //update via web service and update Comment's model by the response or just increment the comment.upvotes 
           //call completion with updated comment
        }  
      }
      
      struct ViewModel {
      
        func upvoteComment(at index:Int, completion: (() -> ())?) {
             commentService.upvote(comments[index]) { updatedComment in
                //do some more stuff with viewModel
                completion?() //in the completion is implemented updating of ui
             }
        }
      }
      

      完成块可以提供更新 ui 的方式,而无需任何委托或通知

      当定时器触发方法时,操作结束可以调用委托方法更新视图。另一种选择是使用绑定框架(例如Bond),然后视图可以观察ViewModel 属性并且不需要委托。

      https://github.com/thefuntasty/MVVMTestProject/tree/master/testMVVM 也许这个项目可以帮助你理解。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-12-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-10-21
        • 2013-04-03
        • 2011-06-18
        • 1970-01-01
        相关资源
        最近更新 更多