ViewModels in Swift & Kotlin

Eric Silverberg
The Startup
Published in
3 min readDec 6, 2020

Everyone’s heard of a ViewModel, but what do they actually do?

A complex, early ViewModel (Photo by David Carboni on Unsplash)

From StackOverflow:

A view model represents the data that you want to display on your view/page, whether it be used for static text or for input values (like textboxes and dropdown lists) that can be added to the database (or edited). It is something different than your domain model. It is a model for the view.

View. Model.

As part of a Clean MVVM architecture, the use of ViewModel classes aligns closely with the classic definition: it holds the state of the view, reacts to user actions to trigger operations that ultimately modify that state, and emits events connected to user actions. It is represented by the green 🟢 parts of Uncle Bob’s Clean architecture.

3 design rules for ViewModels

When writing a ViewModel class for a mobile architecture, consider these three rules:

1. Never reference UI libraries

Never import anything from android.view and UIKit package. From a practical matter, when you have a ViewModel without such dependencies you will be able to write and run tests directly from the command line, without an emulator. The only time we allow ourselves to break this rule is on iOS — we still may use models in UIKit to represent images (e.g., UIImage)

2. Always use Reactive streams

As has been said many times, you should use reactive primitives (such as those provided by LiveData, RxJava, RxSwift, ReactiveSwift, or Combine), and not types directly with callbacks.

You should also be careful not expose mutable streams. For android, this means avoid exposing MutableLiveData / PublishSubject, and instead expose LiveData / Observable. For iOS, this means never expose MutableProperty, instead exposing a Property / Signal (see code example, below).

3. Consider State vs Events

There are two types of data exposed by ViewModels: State and Events. State is something that we need to retain during the lifetime of the view, and can be represented using:

Events are something that need to be handled only once. For example, navigating to a particular Activity or UIViewController because of a user tap on a button, or showing a toast because of the user hitting a paywall.

Here is how state and events get exposed in a ViewModel class:

Naming

Of course naming, and the end of the day, is an aesthetic decision of the developer, and whatever pattern you choose should be consistent. The ViewModel itself should likely be called <feature>ViewModel for example ProfileViewModel or MatchViewModel. Further:

  • The names of the public methods should reflect the action that is performed in the view, for example onStartButtonTapped
  • Methods that react to asynchronous events or Reactive streams should start with handle.

Next up

ViewModels are not the end of the story, not even close! There are many more types of objects and classes to define and use when building a mobile application architecture consistently across iOS + Android.

Next, we describe our stateless logic classes, the point in an application where repositories meet.

More in the series

Other series you might like

Clean API Architecture (2021)
Classes, execution patterns, and abstractions when building a modern API endpoint.

Android Activity Lifecycle considered harmful (2021)
Android process death, unexplainable NullPointerExceptions, and the MVVM lifecycle you need right now

About the author

Eric Silverberg is the CEO and founder of Perry Street Software, publisher of two of the world’s largest LGBTQ+ dating apps on iOS and Android.

--

--

Eric Silverberg
The Startup

CEO, Perry Street Software. Developer. 🏳️‍🌈