Presentation Controls, custom views and lighter UIViewControllers (Part 1)

So we now have MVVM, MVP, VIPER, VIP, but what about the other part? Where should the complex UI logic be placed?

Fernando Martín Ortiz
iOS App Development

--

Note: This is the first of a series of posts in which I am going to discuss some ways to make your UIViewControllers thinner by abstracting them about UI presentation logic. The next posts will be published in the following days.

When I started developing iOS apps, I began as anyone by using Apple’s preferred architectural pattern, Model-View-Controller (MVC). We all know that MVC leads to a very bad separation of responsibilities.

The View Controller acts as a mediator between the view and the model and ends by having a lot of messy code that handles everything, from UI logic and navigation logic to business logic and API calls.

If you have noticed that and searched for alternatives, you probably heard about things like MVVM, MVP, VIPER or VIP. If you haven’t heard about those, I strongly encourage you to try some of them (https://medium.com/ios-os-x-development/ios-architecture-patterns-ecba4c38de52#.6bew98dms).

Every MVC alternative has been thought to address a particular problem and has strong points and weak points, but all of them have one thing in common: they separates the logic from the presentation, making the UI completely interchangeable. And that’s great. The UIViewController is now isolated and can be replaced for another way of presentation without much problem. This is really cool.

When I started developing my own apps using MVVM I noticed that my UIViewController becomes thinner because it didn’t have any business logic, but it seemed that something was missing. The presentation logic was still making the view controller bigger than desired, so I spent some time thinking about that and discovered some solutions. Today I will explain the first of those: separate UITableView protocols from the view controller.

Isolated table views

The first thing I wanted to have out of my view controllers was the UITableViewDataSource and UICollectionViewDataSource. Some people has already talked about how to get the data source outside the view controller.

The idea is simple. When we have UITableViewDelegate and UITableViewDataSource in the view controller, we have to think in terms of indexes, cells heights, cells identifiers, and a lot of low level concepts that we don’t really want to care about. A better approach would be adding a new component to the equation. It could be named Table View driver and managed the table view presentation details.

The plan

We will introduce a new component that will be the delegate and data source of the UITableView and will abstract the view controller about the details.

The table view driver code

There are some things to notice here:

  1. The table view driver stores a reference to the data that it displays.
  2. It also stores a reference to the table view that it manages.
  3. Although the view controller shouldn’t worry anymore about indexes and low level presentation details, it probably wants to know about the high level logic, such as when a item is selected.
  4. The table view driver is the delegate and the data source of the table view.
  5. Finally, it exposes a high level public interface so the view controller can handle it.

The simplified view controller code

By following this approach, the view controller will not only be thinner, but more declarative and will work at a higher level of abstraction. Let see the simplified view controller code:

There are some important things to notice:

  1. We can abstract the view controller from the table view low level presentation logic. However, the view controller will continue to know about the existence of the table view. This is a problem, because we can’t for example, replace it with a UICollectionView without modify the controller.
  2. The view controller owns the table view driver by keeping a strong reference to it.
  3. The view controller is responsible of instantiating the table view driver and assigning itself as its delegate.
  4. The view controller calls the high level methods of the table view driver.
  5. The view controller is the table view driver’s delegate.

Conclusion

We know that the view controller should be isolated from the business logic by encapsulating it in a component like a view model, or a presenter, o an interactor, but the view controller will continue to be responsible of low level presentation logic.

In this post, I discussed the first of a series of methods that we can use to split the view controller in a bunch of components that will be responsible of little parts of the presentation. The first method involves the use of an object that handles the table view (or collection view) presentation logic and exposes a simplified and higher-level-of-abstraction interface to the table view.

In the following posts, I will discuss other methods, like presentation controls, and custom views (programmatically and by using xibs).

If you are doing this in another way, I will be pleased of hearing about it. Please, leave your comments below! Thanks!

--

--