Model–View–View Model (MVVM)

MVVM is a structural pattern that focuses on three pieces:

  1. Model: In the most practical sense, any data to bring on screen. Could be mutable by the user, or static. (Similar to MVC).

  2. View: In the strictest sense, the NSView or UIView subclass, or SwiftUI.View component that draws pixels on screen to somehow visualize the model. (Similar to MVC).

  3. View Model: A representation of the Model that’s designed to cooperate with the View. In SwiftUI, Combine, RxSwift, this is often reactive, driving the UI with live changes.

View Model as Data Transfer Object

The View Model can be a dumb data-transfer object (DTO) that is coupled to the view: when you need to display a person’s age in a text field, you declare age: String to match the text field’s expectation.

This is an important change already and removes a big burden from the mvc: By assembling a special model for consumption by the view, you isolate points for change. You only need to change 1 place where the true Model becomes the View Model. This decouples the View from the Model through another layer of abstraction. The View doesn’t need to know the Model, and it cannot even by accident change database entities, and the Model doesn’t need to worry about being displayable.

Reactive View Models and Cocoa Bindings

The View Model can also be a two-way live view into the app’s overall state, and even some persistence mechanism like a database or cloud storage. The View Model then exposes reactive bindings like @Published properties instead of the usual.

Interestingly, reactive bindings in View Models echo Key–Value Coding (KVC) and Key–Value Observation (KVO) that was possible in Objective-C, and still is if you use dynamic dispatch via @objc. Only KVO was brittle and required runtime checks since it came with no compile time guarantees.

In the extreme case, a mutable reactive View Model is just the modern equivalent of a Core Data NSManagedObject with (macOS exclusive) Cocoa Bindings of UI components directly into the data store. With all its downsides.

Posts on the topic

Jan 5 2020 Maybe Call Your UI Configurion Objects ViewData Instead of ViewModel
Mar 7 2019 Do Not Apply Code Heuristics When You Need a Broader Perspective
Jun 16 2018 Better Form Model Validation
Jun 6 2018 Validate Temporary Form Models
Jan 26 2017 Refactoring – Extract Objects Horizontally or Vertically
Jan 11 2017 Swipe Transitions and ReSwift
Oct 8 2016 MVVM's Place in Your App
Aug 9 2016 MVVM Is Quite Okay at What It Is Supposed to Do
Jul 21 2016 Splitting the View Models of TableFlip, a Short Aftermath
Jul 18 2016 I'll Split Up the Monolithic View Model in TableFlip. Here's What I Expect to Happen
Mar 25 2016 5 Heuristics for "I have a complicated nested view controller setup. How do I handle passing data?"
Jan 16 2016 How to Couple UITableView Cell Identifiers and View Models
Dec 19 2015 Separate Read Model from Write Model to Support Complex Forms
Dec 14 2015 iOS View Architectures and VIPER Explained
Nov 25 2015 Presenter and MVVM for UITableViews?
Oct 16 2015 Achieve More with a Variety of Value Objects in Swift
Oct 14 2015 Decouple UI from Model with View Models and Controls
Jun 19 2015 So I've finished my model, now what?
Jan 23 2015 Model–View–View Model (MVVM) Primer
Dec 19 2014 Model-View-View Model in Swift