iOS Architecture: MVVM-C, ViewData’s (5/6)

Daniel Lozano Valdés
Sudo by Icalia Labs
3 min readOct 4, 2017

Why ViewData?

This is a little bit of a controversial concept, and you won’t usually hear it mentioned when talking about iOS architectures, not by this name at least.

This is basically an off-shoot of the ViewModel concept. I learned about this concept after hearing an awesome discussion on the Fatal Error iOS development podcast, on their ViewModel episode, in which Soroush Khanlou mentioned using something called a ViewData. I don’t really know if his idea of this concept and mine are completely equal, but I’ll try to at least explain mine.

The reason why I say this concept might be controversial is because reading up on ViewModel’s on the web I realized that there were two camps. On the one side some developers think ViewModel’s should be these reference based, live objects that make network requests and all sort’s of stuff. Basically, what I explained on the previous article on ViewModel’s.

But there was another camp, which said ViewModel’s should be much simpler, just a simple struct. It should do no network request or anything of the sort. It should just be a simple wrapper around a specific Model which formats it’s properties for presentation by the view, but that’s it. No two-way back and forth communication.

Altough I came on the side of that ViewModel’s should be live objects handling all the business logic, that’s why I decided to use term Soroush coined, this other concept of a ViewData and use that as the simple wrapper around a model. Best of both worlds!

What is a ViewData?

So in simple terms, a ViewData is just a dumb wrapper that takes in a model like for example a Trip and wraps it up in struct called TripViewData. This ViewData can then be sent from the ViewModel to the ViewController, without having to send the bare model. As we know the view should not be dealing directly with model objects, and since MVVM considers the ViewController part of the View layer then we must give the ViewController already formatted data ready for presentation.

So a ViewData is basically a much simpler, inert version of a ViewModel that we can use to wrap around our model objects.

Let’s see some code

As always, we start with a protocol. Our View layer should not depend on a concrete implementation. It is quite common that we might want to use a different implementation of this same ViewData in a different part of our app, or do some testing as well.

In this case we have a Trip model, therefore we create the TripViewDataType protocol.

The protocol should have any user facing, formatted for presentation properties the ViewController/View might need from our model. The View layer should have to do no extra work to get this data ready.

Then we can implement our protocol using a struct.

Our view data implementation should do two things:

  • Have an initializer in which we get the actual model and any other extra information we might need.
  • Implement the ViewData protocol so the View layer can get everything it needs from the model without actually seeing the model.

Usage

This is how we might use the ViewData in our Trips ViewModel.

Our ViewModel has access to all the Trips. But whenever the view asks for one of these trips it returns a TripViewData to it. Remembering to return the protocol signature, not the actual concrete implementation.

Conclusion

That’s it! This ViewData concept is basically just an off-shoot of the ViewModel concept, and when these two concepts are used in tandem it can be a powerful way to design your architecture. ViewData’s wrap around Model objects to prepare them for presentation by the View, they have a one-on-one relationship with a Model. They are similiar to the adapter design pattern. ViewModel’s can also do that, but they are a more powerful concept that do much more than wrap around models, and they have a one-on-one relationship with the ViewController’s.

Up next, in the final article in the series we talk about Services.

iOS Architecture: MVVM-C, Services (6/6)

--

--