3 min. read

Model-View-ViewModel (MVVM)

a view model is a companion object to a view controller.

Model: App data that the app operates on.
View: The user interface’s visual elements. In iOS, the view controller is inseparable from the concept of the view.
ViewModel: Updates the model from view inputs and updates views from model outputs

Reduced complexity: MVVM makes the view controller simpler by moving a lot of business logic out of it
Expressive: The view model better expresses the business logic for the view.
Testability: A view model is much easier to test than a view controller. You end up testing business logic without having to worry about view implementations


The view controller is only responsible for altering views and passing view inputs to the view model

the view model is responsible for the following:

Model inputs: Taking view inputs and updating the model.
Model outputs: Passing model outputs to the view controller.
Formatting: Formatting model data for display by the view controller.

Normal MVC:
WeatherViewController.swift - This is the view controller you’ll refactor to remove any use of model and service types.

DarkSkyWeatherData - is a struct that represents the data returned by the Dark Sky API
Location - is a simplified struct for location data Apple’s CLLocation service returns.

DarkSkyForecastService - fetches the weather data from the Dark Sky API
LocationGeocoder -

Storyboards contains LaunchScreen and Weather storyboards.

In MVVM, you need a way to bind view model outputs to the views.
To do that, you need a utility that provides a simple mechanism for binding views to output values from the view model

Key-Value Observing or KVO: A mechanism for using key paths to observe a property and get notifications when that property changes.
Functional Reactive Programming or FRP: A paradigm for processing events and data as streams. Apple’s new Combine framework is its approach to FRP. RxSwift and ReactiveSwift are two popular frameworks for FRP.
Delegation: Using delegate methods to pass notifications when values change.
Boxing: Using property observers to notify observers that a value has changed.

When a Listener calls bind(listener:) on Box, it becomes Listener and immediately gets notified of the Box‘s current value.

func bind(listener: Listener?) {
self.listener = listener

In MVVM, the view controller doesn’t call any services or manipulate any model types. That responsibility falls exclusively to the view model.

In MVVM, the view controller is only responsible for views. The view model is always responsible for formatting data from service and model types to present in the views.

References and Resources