Skip to content
Michael edited this page Jul 10, 2016 · 5 revisions

The role of a view model is to aggregate, transform or otherwise process model data to provide bound views with bindable data and on the other side to process user interface events and update model data or trigger other activities in response of such events.

View Models support abstract user interactions

Even though view models are responsible to support views and view bindings, they can and should be as independent from the concrete user interface as possible to enable reuse and provide flexibility.

In that sense, view models represent the state of an abstract user interaction that is implemented by some user interface.

Examples

Independence from concrete UI controls

For example, if the abstract user interaction is to edit a number value:

  • The view model has a number property (f.e. @property double value), the state of the user interaction is the value of that property
    • The view model may also have a maximumValue property (f.e. @property double maxValue) that might depend on some system state and that determines the range of the number value
  • The user interface can be a UIStepper, UISlider, a UITextField or some other control.
    • User interface controls supporting a maximum value (f.e. UIStepper or UISlider) can make use of that property

The view model does not know anything about the user interface control that actually displays the data and thus can support all these rather different controls and changing the presentation does not require any code changes.

Independence from formatting choices

For the use case to display and edit a date value:

  • The view model has a date property (NSDate), for example @property NSDate* date
    • If the rendering of the date depends on the state of the user interaction or some other system state, the view model can provide a formatter property that adapts to that state.
  • The user interface could be a UILabel wrapped in a AKADatePickerKeyboardTriggerView (extension provided by beacon) or a UIDatePicker.
  • The binding specifies a formatter
    • The formatter can be specifically created an customized in the binding (see formatter bindings) if that presentation is unlikely to be reused in other places.
    • The formatter can be provided by an application-wide enumeration of shared formatters and referenced from the binding, if the format is used in different places.
    • The binding can reference a formatter provided by the view model, if the format depends on the abstract user interaction state.

Again, the view model does not (have to) know about the views presenting the date neither about formatting, unless the formatting is part of the abstract user interaction state.

As a consequence, the view model does not depend on visual aspects of the presentation, internationalization or localization (Storyboards support localization, so it makes sense that you define locale sensitive customizations there).

View Models vs. View Controllers

For simple use cases it is often convenient to let the view controller fulfill the role of a view model. This is a good choice if:

  • The view controller is basically not doing anything else
  • The view controller does not have presentation specific code (does not implement delegates, does not contain customization code that cannot be expressed in storyboards).
  • It's unlikely that you want to reuse the view model in a different context.

The advantage is to save the extra class to define for the view model.

However, in non-trivial cases it is most often advisable to provide a separate view model for the obvious reasons (most importantly reuse and avoidance of spaghetti code clusters)