iOS App Architecture for Web Developers

Chloe Verity
Songkick Tech
Published in
6 min readOct 16, 2020

--

Part 3: View Controllers

This article is part of a series of posts dedicated to helping web developers new to mobile development bridge the gap between building web apps and iOS using the common MVC pattern, as told by two developers at Songkick who have recently made the jump themselves.

If you haven’t read the previous post, please click here.

If you’ve made it this far, well done!

There’s only so many times I can introduce what the MVC pattern is using the same diagram — so this time, let’s use an analogy. I want you to think of your favourite meal. Mine is a good ol’ pepperoni pizza. Now, let’s say, for some reason I wanted to make my own pizzas for a pizza party I’m having with my friends; imagine I’ve filled the fridge with all the raw ingredients. We have all the makings and mechanics of a pizza stored away in there: the necessities like dough, tomato sauce, mozzarella, and some other bits and pieces for toppings, that will be used depending on the wants of the person eating it. That’s basically the Model in a nutshell; a data blueprint (of a pizza).

And if, as we saw from the previous instalment in our series, a View encapsulates all that the user sees and is able to interact with, then at our pizza party, the View is each encapsulation of a pizza that sits before one of my friends; a combination of their choices (toppings) while still abiding by the fundamental architectural rules of the pizza (for example, without dough, it’s not a pizza, and no, we’re not counting cauliflower pizzas). So, then what the hell is a View Controller?

In this case, the View Controller would be the recipe. The recipe dictates the logic behind how we use the raw materials/data from the Model, and how we turn it into something tangible that the user can see and interact with (the View). It’s flexible (there are many different recipes that give you a pizza), yet if the View Controller isn’t doing it’s job correctly, then the final product isn’t displayed on the screen properly, much like how you could assemble the ingredients in any way, but you might not end up with something that constitutes a pizza.

So what actually goes in the View Controller?

View Controllers, considering they are the bridge between the Model and the View, are largely considered to be skewed towards the View; each View Controller (usually) represents one screen of the app, and has one or more corresponding Views to make up that screen.

As discussed in the View portion of this series, the View Controller contains references to most, if not all, of the objects that appear on the View. This is to handle user input, or so that they can be interacted with; for example, in the View Controller, we can give a button specific instructions on what it needs to do when pressed. We do that like so:

Anatomy of a button created programmatically

In this example, we can see that on loading the View, we first give the viewAllButton several properties, such as colour, title colour and title text. The reasons you might want to set these attributes programmatically are manyfold; you might want to localise the text so it can appear in 15 different languages, you might want to, as shown above, manipulate an attribute depending on the state of the object (as we can see where we set a different title colour for the button depending on whether the button is selected or not), perhaps you want to reuse the object later, perhaps you want to populate text or manipulate the View depending on data from the Model (or maybe you just have a general aversion to interface builder), all are perfectly valid.

The next thing to do is add a target to the button, which has three parameters: the target, an action, and the control events. The target is the object whose action method is called. The action is the method you want to invoke when the object is interacted with, and the control event is the type of gesture event that launches it (touchUpInside is the most used gesture, for it reflects a simple tap, but there are several that you can invoke this way). Think of this as the Swift version of an event listener.

And finally, you need to create the method that you want to call. Throwing it back to Models in Section 1, we might need to create, update or delete database information via our Model. Imagine serving your friend a pizza, but lo and behold you’ve forgotten something: you go back to the recipe (View Controller) and realise you’ve forgotten the anchovies, so you go to the fridge (Model) to grab them, use the recipe again to understand that, yes, they’re placed on top of the cheese, and once you’ve executed those instructions, voilà, your friend is served again with a delicious, updated pizza (View).

It might be apt just to call a method in our View Controller, or, if the View Controller in which this method lives is the child of another, and we need access to the parent controller’s methods and variables, we might need to pass this method call up to the parent via a delegate. Above, I’ve simply printed something, but as I said, this could be anything your heart desires.

Why MVC?

MVC is not unique to Swift; if you’ve ever built a Rails project you’ll know that you should have separate folders for each Models, Views, and Controllers, making it easier for you to identify and understand what each individual piece of code does, and where it fits based on that functionality.

Now, the ideal scenario is where responsibility is pretty equally spread between the Model, View and Controller. The reality is, however, that the View Controller ends up with disproportionately more responsibility than the other sections, since they seem to lend themselves more naturally as the “place to put things”. What I mean by this is that, if something doesn’t immediately appear to fit the bill of “logic” or “design”, then it gets lumped in the View Controller without a second thought, and before we know it we end up with these massive View Controllers.

This impacts navigability, sure, but you’ll find that actually, if used as intended, MVC structure makes it easier to navigate through and understand what’s going on in the code base, and makes it possible for people to not only make modifications and debug, but for multiple people to do so simultaneously due to the separation of responsibilities.

For this reason, if your app necessitates structure and relies on performance, MVC is a good contender, if you are working on a single page app, you probably shouldn’t bother. MVVM (Model, View, View Model) is an alternative, which, rather than having a Controller which ensures that the Model and View don’t talk to each other, has a View Model that actually binds the data between the View and the Model, allowing them to directly talk to each other. MVVM would be the choice for a single page app, since it’s simple and allows direct communication and therefore can move quickly and continuously save to databases. Yet, since it relies on binding the data, it consumes a lot more memory, meaning that it would not be the first choice for larger applications, who as we’ve said should probably be using MVC.

In pizza terms, MVVM would be like me making all my friends’ pizzas relying solely on my memory — that’s fine if they all want the same thing, but if they don’t, I’d be better off having the recipes in front of me. Ultimately, choose the way that’s going to get the pizza on the table, fastest, easiest and leave everyone satisfied.

Happy p̶i̶z̶z̶a̶ ̶m̶a̶k̶i̶n̶g̶ engineering!

--

--