MVVM + POP to deal with complex UI

Mohshin Shah
NE Digital
Published in
8 min readSep 7, 2022

How to use MVVM with POP to code and solve issues while designing and coding complex UIs. with examples.

Hello 🙋,
Firstly,
MVVM stands for Model View ViewModel
POP stands for Protocol Oriented Programming
If this title doesn't ring a bell for this abbreviationsđŸ˜”â€đŸ’«,
Nothing to worry, I will cover the basic foundation and ideas.

MVVM? Why not the MVC for iOS Development ?

While doing iOS devs, you must be knowing that UIViewController comes with a View in built. Now you wonder what is an issue with that.
Well, there are a few things which it evolves doing so if you go with this.

  1. As your view is inside your controller, and all UI and controlling logic like making network calls, data base ops, formatting data etc. happens inside where the view is. (Now someone would argue that we can use a separate class to make network , db ops etc but still your VC stays the main hero to initiate this). So at the end of the day what happens if your stakeholders or business team decides to change the UI or want to show profile page from somewhere else not from this screen, YOU WILL END UP changing UIViewController again and again for UI changes
  2. What if you want to write test cases for the business logic for this screen like showing data is correct, how to handle a not-logged in user, tracking analytics for a specific click. WE CANT ! coz it’s not possible until we create a UIViewController. And moreover if you are using a UIStoryboard, You will end up with a lot of work arounds.
  3. Plus, your UIViewController becomes bigger and bigger when you add more screens, routing, more logic, (Some says we may use helper and wrappers but then Point 2 😐)

So what can be done to solve this kind of problems, We can use few architecture pattens like MVVM, MVP, Clean, Viper, in all of this MV* patterns, your * is a component which tries to break this View dependency of a UIViewController. Either by providing data what view needed without putting it inside VC or Moving Routing decision to some where else and ultimately makes your UIViewController a VIEW component. I repeat again, making your UIViewController a simple VIEW component.

So now you are eager to ask me, what are the advantages ? This will make your view a dumb view component, meaning not having any business logic inside, no control of doing stuff, routing etc. HENCE we have separated our view, woah! and now we can test our other components ,as usual without creating a view. Plus nothing gets affected if we change UI or View. Is not that great ? Like if you get a task to change UITableView to UICollectionView, and you are like, OKAY, Easy to do. Lol.

Basic Idea is Separation of Concerns, no matter if its an MVVM or any other (MV-*) patterns

M-V-VM: M-V-(ViewModel -> Model For View)

Anyways, That was some idea about MVVM. MVVM stands for Model View ViewModel. And if you are confused, let me clarify, in the MV* architectures I explained above, here the * is our ViewModel. A model for View, a model to which has data for view. OR OR A model which avails formatted data for view 😉.

Now I hope you are clear about what MVVM does and what are the pros, cons.

So There are a couple of things I have derived is,

  1. View Component (Note: UIViewController is View) can have a ViewModel inside and it relies on it only.
  2. ViewModel: A component responsible for doing all the work and prepares data for View to consume. A ViewModel can have a Model in it
  3. Model: Well, nothing changed here, a data model or a value type

Question: Oh Wait a moment, Does this mean MVVM is an architecture pattern ?
- I would say its more like solving the UI level separation so it is solving an issue which is the View(Interface) separation from Controller (Here controller is a C in MVC). It is not solving any other aspect of your application though. Hence it is not exactly an application architecture pattern but a UI design pattern.

I hope the above has cleared the idea about MVVM for you. Let’s see what is this POP thing is. If you are an iOS developer you must have heard of Protocols. And if some other coding background it is the same as Interfaces.
Interface/Protocols/Abstraction this all refers to the same idea of solving many things. If you heard of SOLID principles, many of the principles eg. Open/Close, Liskov Substitution, Dependency Inversion etc have this Interface/Protocol/Abstraction idea at the core. You may check my series of SOLID principles for more detailed information here.

Now with the traditional SuperClass-SubClass, there are some issues, you may have also experienced eg. Empty Function implementations or fatal error with “subclass must implement it”, or a down casting. You may check this if interested. https://developer.apple.com/videos/play/wwdc2015/408/.

Protocols in swift actually gives more power like,

  1. You can create a protocol and have an extension on this protocol to have a default implementation.
    - Doesn’t this sound like a super class implementation. You have an implementation that all subclass will have by default.
  2. Protocols allows you to write an extendible code. Eg. You may have extension on the Existing classes, enums, etc and add more functionalities to it without subclassing it.
    - This is amazing, no? You can have a similar thing like subclassing without actually doing it.
  3. Multiple inheritance. Either You can make a protocol which inherit from a protocol or multiple protocols or you can conform multiple protocols which solves the multiple-inheritance issue. Please check example for the in the images given below.
    - Which gives you flexibility and extendibility for your code

Look at this Array code in Swift codebase, Extendible and No subclassing at all.

Protocol Inheriting another protocols.

Yes This is the POP — Protocol Oriented Programming. Using protocol to write the code not using class hierarchies. It would solves many issues. Creating protocols grouping similar behaviour methods in to one. “High Cohesion, Loose Coupling”
Later you can either compose this protocols to one or a protocol which inherits other protocols for better naming. Check this `Codable` Protocol in swift.

Now I really hope you understand the MVVM and POP ideas. Let’s see how can we make our ViewModels more POP way.

Let’s understand this with an example. There is an UI given as below and you would like to write the code for this list. What would be the approach first.

Example mobile UI. Write a code to cater this UI

Okay first you would assume there would be a ContactListViewModel and it will give you the data what’s necessary for this listing.and There will be one ContactCellViewModel which will give the data for each cell UI. So far so good. It is surely a good way to do this.
1. ContactListViewController depends on a ContactListViewModel
2. ContactTableViewCell has a ContactCellViewModel

All good. Nothing wrong in that.

Diagram 1

But the things get complex when you have heterogeneous UI in the list. Let’s see another example of list UI.

Complex UI, can not use the same ViewModel to render all the cells, because they are heterogeneous.

In this UI, we can not use an array of CellViewModels to represent cells, as all the cells have different UI and behaviour and in that matter we cant even use a single CellViewModel to represent all the cells. And if we do that it will end up writing the unnecessary or blank codes for the cells which doesn't need other features. Eg, Date selection for first Title input cell.
So how to solve this issue ?

Yes got me correct, Using a POP

As we know that ViewModel has everything that a View requires, why not we make this mapping using an abstraction. Using a protocol. Like for the first cell only one thing is needed which is Title text. (lets not discuss the input, validation etc else it would be another topic).

Using a Presentable Protocol

First of all lets create one Protocol/Interface which represent the all the cells itself and define common things there. a `Presentable` protocol
eg. `TaskListItemPresentable` and as we can see all the cells have a title. Lets define it here.

Defining the presentable protocols for a view. Whatever data a view would require to render.
Defining the presentable protocols for a view. Whatever data a view would require to render.

And then ListViewModel can now have the array of `TaskListItemPresentable`.

Now create the respective ViewModels to conform this protocol and provide necessary data.

Conforming the presentable to the actual viewModel to provide actual implementation.
Conforming the presentable to the actual viewModel to provide actual implementation.

ListViewModel now have flowing the viewModels wrapped inside a protocol `TaskListItemPresentable` and cells will get appropriate viewModel for further processing and ask ask the presentable for rendering data. Which ultimately will get resolved at correct ViewModel. eg. if a First title cell receive a presentable TaskNameInputPresentable and set a label title using presentable.title, ultimately a viewModel instance is providing the data.

Diagram 2

Consuming Presentable Protocol in a View

Your View layer can be anything which is a user interface. It can be an UIView, or a UITableViewCell, UICollectionViewCell etc. Let me give an example for how we can consume the above defined protocols in the view.

Consuming Presentable Protocol in a View

If you can see from the code and also from the Diagram 2 given above, view is actually interacting with a `CellViewModel` which is wrapped inside the presentable protocol.

View uses a Presentable which is actually a ViewModel wrapped in Presentable

Note: The ViewModels and protocols created for example purpose, there are many more advanced ways to do better for handling events, binding, updating UI reactively etc.

Really hope you like this article. Thank you for reading :)

Please feel free to reach me at mohshinshah@gmail.com for feedback or any suggestions.

--

--