When building our apps, its fairly well known that passage models into our views leads to bad things. I don't want to say its a black and white POV but its rarely a good idea or even necessary to begin with.

An often recommended approach is to use a ViewModel or Extension to add properties that provide UI representations of our models data. I’d like to suggest a slight alternative that testable and scalable even across large projects.

Example

Lets say we have a simple type to represent a Product. We might have a Model similar to the following:

struct Product {
let title: String
let price: Decimal
}

A product can have a title and a price. We don’t want to lose our underlying types, but at some point we need to present the price to the user in their local currency.

View Model

One solution to this problem is to introduce a View Model.

struct ProductViewModel {
let title: String
let price: String
}

While this approach is highly testable and allows you to abstract away the presence of the original Model, it also comes with some caveats.

The name of the ViewModel is tightly coupled to the original Model itself, and so refactoring could be painful to keep these names in sync. This is the #1 issue I’ve faced myself.

Often leads to some duplication where the value can be mapped directly.

While this approach isn’t inherently bad – as long as you keep it immutable – one of the biggest issues arises when you start naming things. You can already see that we now have a price as well as a priceString variable to make it clear that the latter returns a string representation of the price.

Descriptors

An alternative approach I’ve come up with that I’ve battle tested and had proven success across even large projects, is something I call View Descriptors.

Its basically a merge of the above concepts. Where the Descriptor is a dedicated type that’s added to your model type through an extension.