Changing UIViewController but keeping the behavior

Rodrigo Cavalcante
Cocoa Academy
Published in
3 min readDec 4, 2017

Hello everyone this year I’ve learned a lot stuff like code review, testing, viewcode and more. This is probably my last post this year and I decided to talk about something very interesting that I saw on my last project.

You probably already had to change some UI of any project maybe just a few labels or every single view on it which can be very tricky. And if there’s a way that we can build a new UI from scratch and still be compatible with our previous one.

Our challenge was to build a framework that can be easily customized with new UI’s but it needs to keep the logic untouched, when I said new UI I mean an entirely new UIViewController.

How can we create an architecture that will be able to handle that? e.g. how we can receive a custom UIViewController instantiated by a storyboard, viewcoded or black magic and still authenticate our user?

To achieve this we need to split our logic into separated files with it owns responsibilities and keep their dependencies in mind e.g. a LoginViewController should have a username , password and a login method.

First, we need to take out the login responsibility and move it to another class that will actually do the authentication process. This removes the responsibility from our ViewController making it decoupled to our authenticate logic.

Let’s create a protocol that will do that:

LoginActions protocol

Username and password are dependencies from our UIViewController. We need these properties to show something on UI. Your dependencies can be anything like a User object or array for example.

Now we need to create a class that will have these properties and actions (username , password and a LoginActions's delegate)

LoginViewController

This will be our base class any custom Login’s UI should inherit from LoginViewController.

Let’s create a new UIViewController called LoginView1:

LoginView1

And another one called LoginView2:

LoginView2
Left: LoginView2— Right: LoginView1

Notice that neither of our LoginView actually authenticate our user, they receive a boolean value that indicates that if the user was authenticated or not. The authentication process will be done by our delegate that can be implemented in many different ways. Here we are going to create a coordinator that will implement our LoginActions.

Our coordinator start method returns a LoginViewController which can be created by a storyboard file, viewcoded or injected in another way. It will be responsible for authenticate our user in this example, but fell free to remove this responsibility from it and put in another file.

Removing responsibilities from our UIViewController make it highly customizable, decouple to any kind of logic, more testable, readable and cleaner. Just don’t forget to keep the dependencies in a base class, they will be needed in any implementation.

Ps: If you like this post, share it on twitter, recommend it on medium, or both =). This really helps me to reach more people. Thanks a lot.

--

--