1 min read

View Data

Last Updated - Platform 21.0 - SDK 16.0

Views are updated using their associated ViewData. To send custom data to a view use the customData property of the view data model (read on below).

Protocols vs Structs

Prior to v21 ViewData was created as an interface and implementation pair allowing developers to provide their own implementation to pass custom data to the View. However, this format had a number of drawbacks:

  • The developer must provide their own implementation of the ViewData and Mapper.
  • The developer must use casting to access their ViewData type.
  • Equatable has self requirement so ViewData cannot be easily composed.
  • Where ViewData was composed the Equatable implementation must be manually provided which often caused issues.

From v21 onwards we have moved to using structs with customData. The major benefit of this move is to provide better Equatable conformance, but this also reduces the amount of custom code required.


Mapping is a key pattern across the SDK. We use mappers to map between data and domain models, and between domain and view data models. The following diagram highlights how ViewDataMappers fit into a feature's architecture.

ViewDataMappers are protocols with open class implementations, and can be injected via initialisers or replaced (or decorated) via the shared Container. The main ViewDataMapper of a feature can also be replaced using the withViewDataMapper() function of the builder.

Custom Data

From v21 onwards all ViewData models have customData. Use these properties to pass custom data to the view. The default implementations of the ViewDataMappers forward the domain model's customData directly into the view data model's customData property.

To provide the custom data you can either customise the mapper for the domain model so that it creates a CustomData domain model, and then rely on the default mapping logic to forward that to the ViewData.

Or you can additionally, or optionally if the domain mapper forwards the AnyCodable custom data from the data model, map the customData from the domain model into a CustomViewData model for the ViewData.

To use the customData you will need to subclass the view and override the setUp(with:) function. In your implementation you can use the following to access your custom properties.

override func setUp(with viewData: SomeViewData) {
super.setUp(with: viewData)
customLabel = viewData.customData(CustomData.self)?.text