Make MVVM Great Again!

For my last post over my ZombieInjection experiment, I wanted to cover the overall MVVM architecture that I used in developing this example app. As I was doing some research for this post, I discovered that the way I learned MVVM was very different from what appears to be how many in the iOS community learned about MVVM.

Some Background

I first learned of this architecture pattern while I was doing Xamarin apps in C#. This meant that there were a lot of articles and very mature examples on implementing MVVM in the .NET world that I could draw on to learn this powerful architecture pattern. As I compare what I learned in .NET to how the iOS community is typically implementing this, I am seeing some missing pieces on the iOS side. Namely, if all you are doing is taking a typical MVC application and refactoring it to fit this pattern, MVVM is probably not very compelling for you. In fact, some respected iOS developers have come to the conclusion that MVVM is Not Very Good.

While Soroush’s post has some valid points, I believe it is missing a lot of context and incorrectly comes to the conclusion that this architecture pattern should just be ignored. I will attempt to fill in that missing context and Make MVVM Great Again!

 MVVM Overview

Before we get into some of the missing context, I wanted to give a brief overview of MVVM. Disclaimer: This is MVVM as I know it. It seems like there are many different flavors and preferences but this is what I’m familiar with so I would love to hear other techniques or ideas to further simplify or enhance my own understanding! The graphic below is the best representation I’ve found for how MVVM looks in iOS:

Next, let’s define the different parts that make up the MVVM pattern as it sounds like there has been some debate as to what roles these components should play.

 

Model

The model holds the actual data and/or information that we will be dealing with in our application (typically called the data layer). As its main goal is just to hold the data, it should not be holding *ANY* behaviors or logic that manipulates the data/information itself. It is *NOT* responsible for the beautification of the text on the screen or fetching new items from a remote server. In a perfect world, it is a very clean and simple structure. For example, the Zombie model structure in my example project is solely responsible for holding the id, name, image, and image URL — that’s *ALL* it does. (Other than holding a RealmPersistable that allows me to better isolate the rest of my app from Realm specific logic 😉)

Here’s what it looks like:

Side note: As somewhat of an MVVM purist I don’t particularly like having UI elements such as UIImage in my models but for simple things like this it’s much easier to just deal with it that way.

View

The view, in conjunction with the view controller, make up the “View” component in the MVVM pattern in iOS. The view is the thing that the user is actually interacting with in your application; it is also the place where you will be presenting data.

The most complicated view in my example project is the ZombieListViewController. It is responsible for surfacing a list of zombies in a UITableView, handling the data-binding between the view and the view model, and handling the navigation logic to the detail view for one of these zombies if you click on it. At some point, I’d like to find a way to push the navigation logic into the view model for easier testability but this will have to do for now.

My ZombieListViewController looks like this:

View Model

The view model is what controls what is being displayed in the view. It retrieves the information from your data-layer (your models), formats it if necessary (I’d love to figure out a way to implement ValueConverters in Swift), and passes it to your view. In my example, the view model is simply retrieving the data to be shown from a ZombieService and exposing the ImageDownloadService so that the view can show the correct image.  After it has the data we need, it uses Data Binding (via the Bond framework) to actually update the view.

One of the main points of contention I’ve seen is that some developers have been advocating doing your network calls/fetching data directly in the ViewModel itself… Don’t do that.

My ZombieListViewModel is fairly basic; It handles the update of the list of zombies via the ZombieService and exposes the ImageDownloadService so that the view can download the correct image via it’s binding.

Now that we’ve gone over the high level detail in how I implemented MVVM in my sample project, let’s talk about what I’ve seen missing in many of the other MVVM examples I’ve seen during my research that appear to throw folks like Soroush off.

So, What Are They Missing?

Data Binding

Data binding is one of the staples of using the MVVM pattern in .NET. Unlike in .NET, there is no nice, built in mechanism for data binding in iOS. You either need to do it manually using Key-Value Observing (KVO) or use a framework like Bond. So far, I have loved the Bond framework because it provides a simple and concise mechanism to set up your data binding for multiple objects. For example, in my main list view controller I perform data binding for the text property and image property of all cells of the main table like so:

With that relationship set up, any changes made to the data get automatically displayed on the UI without any more additional work! This eliminates so much boilerplate code and makes things in general much more maintainable.

Dependency Injection

Dependency Injection (in combination with the MVVM architecture pattern) is especially powerful. When combined properly, you end up with a highly decoupled and highly testable architecture. For instance, this setup allows me to easily mock any of the injected dependencies in my project for my unit tests so that I can easily abstract out complex functionality that is not relevant to the specific unit test. Loosely coupled code doesn’t just enhance your testability — It also increases the reusability and extendability of your code.

My project is making use of the fantastic DIP framework. When using this framework, it is recommended that you set up a composition root (also known as the single place where you define *all* of your dependencies for your project):

As you can see above, by default it is set to use Realm as my data repository for my zombie objects; however, by commenting out 1 line of code (and uncommenting the other), I can easily switch to using an in memory data service based on arrays instead of Realm if I just need to debug something and don’t want to mess with Realm. The wiring of the actual AppDelegate looks like this:

The AppDelegate is in charge of resolving the specific dependencies I need and then injecting them into my application via the top level controller. In this way, I’m able to use protocol oriented programming to inject different dependencies just by changing my composition root as these protocols are propagated throughout the rest of the app. Speaking of protocol oriented programming…

Protocol Oriented Programming

If you’re not doing it — you should be.

I won’t go through and fully explain protocol oriented programming in this post, but I highly recommend you go watch the 2015 WWDC video introducing the concept. There are now a ton of resources dedicated to the topic and it will be well worth your time doing some research on it. That said, protocol oriented programming and the MVVM architecture go very well together. For example, take a look at my ZombieListViewModel again:

As you can see, there is a ZombieServiceProtocol and an ImageDownloadServiceProtocol. This allows me to inject whatever objects I want that conform to those protocols inside my ZombieListViewModel. While not immediately obvious as to why this is advantageous, let’s take a look at my unit tests in ZombieListViewModelTests:

As you can see above, this allows me to replace the objects normally expected by the view model with my mock objects. I can then create unit tests that actually isolate the code I wish to test instead of worrying about something like Realm in the unit tests, as it has been mocked out using arrays in my ZombieRepositoryMock. This is BIGLY important to a well architected app that needs to be highly testable.

This is also what allows the dependency injection previously discussed to work. The ZombieServiceProtocol is used everywhere throughout the app. The actual concrete class used for the ZombieServiceProtocol is defined in the composition root as discussed prior. The composition root  registers the ZombieService I want and the AppDelegate injects it into the app to be used. Pretty neat, huh?

Repositories

The concept of repositories was one that was pretty common to .NET land while I was there. I have not seen it much on the iOS side of the fence; however, I am HUGELY a fan of this design pattern. Using repositories allows you to separate your data layer cleanly from the rest of your application. Let’s take a look at my ZombieRepository as an example:

The big thing here is that this repository takes in a ZombieDataServiceProtocol via constructor injection. This is the magic sauce that allows me to easily swap in and out database types. For instance, I can use Realm or an in memory database simply by sending in different implementations of ZombieDataServiceProtocol. While in practice you are not likely switching database technologies frequently, you likely want to switch to a more manageable database type for your unit testing. Take a look at my ZombieRepositoryMock:

With that implemented, I can now use this well controlled, in memory array of objects to do all of my unit tests instead of having to mess with Realm at that level.

Service Layer

Service Layer typically makes use of a repository and captures any of the business logic around that a particular item.

In my example project, the service that best demonstrates this concept is the ZombieService:

In this service, I have encapsulated all of the things you can currently do with Zombie objects in my application. You can fetch them from a service (Mocked out presently), you can update them, and you can get all of them that currently exist in your local repository. In this arrangement, any time you want to interact with Zombie objects — you have to go through the ZombieService.

You’ll notice this is the only place where you get access to the ZombieRepository. This nicely encapsulates the functionality and makes it highly decoupled and testable.

Conclusion

While some of the criticisms of MVVM on iOS are warranted, I believe that this architecture pattern should not be overlooked if implemented properly. When compared to other patterns like VIPER or clean architecture, I contend that you will get the same level of scalability, decoupling, and testability in MVVM without a lot of the confusion and overhead that comes with those other architectures. I hope with my ZombieInjection project I’ve been able to convince you to take another look at this architecture and hopefully I was able to Make MVVM Great Again!

Putting the Injection in ZombieInjection

Apologies about the very long delay between posts. We’ve been getting ready for a new addition to the family so we’ve been very busy! In the mean time I’ve updated all of the 3rd party libraries that ZombieInjection depends on and brought it up to the latest version of Swift.

I still wanted to go into more detail about how dependency injection works in my ZombieInjection project. When I was first trying to wrap my brain around this concept, a full fledged example of seeing it in action would have really been beneficial a few years ago… I hope this is helpful for you!

Spoiler: Yet again, Swift’s generics system puts a damper on things 😔

What is Dependency Injection?

Let’s start with some definitions.

From what I can tell the first use of the term “Dependency Injection” is by Martin Fowler when he described this concept in his blog post, Inversion of Control Containers and the Dependency Injection Pattern way back in 2004, as:

The basic idea of the Dependency Injection is to have a separate object, an assembler, that populates a field in the lister class with an appropriate implementation for the finder interface

Ok that definition doesn’t quite work for me. Moving on.

Mark Seemann, author of the excellent book Dependency Injection in .NET defines Dependency Injection as:

… a set of software design principles and patterns that enable us to develop loosely coupled code.

That’s a little better but kind of nebulous still… Moving on.

The simplest definition I could find comes from James Shore, thought leader in the Agile software development community:

Dependency injection means giving an object its instance variables. Really. That’s it.

Mind. Blown. Is that really all?

Let’s take a look at a super simple example. Below is an example of a simple struct that creates a private NonInjectedObject at initialization and is not making any use of dependency injection:

Now let’s take a look at the same example code except architected to use dependency injection:

You might be thinking… Uhhh OK, all you did was force the person calling the initializer to send in your object… Bingo!

Admittedly, this is a contrite example and doesn’t show you the full benefit of proper dependency injection. Let’s abstract our example class even more and use protocol oriented programming in conjunction with dependency injection:

Now that’s what I’m talking about! In the above example, you have now ended up with a decoupled and highly testable solution. You can easily mock the injected dependency for your unit tests so that you can easily abstract out complex functionality that is not currently part of the test you are trying to write. Loosely coupled code doesn’t just enhance your testability — it also increases the reusability and extendability of your code.

The example I used above used a type of dependency injection called Constructor Injection. Mark Seemann describes 4 types of dependency injection in Dependency Injection in .NET that you can make use of (Yes, I realize I keep referencing a book that mentions .NET in a blog post for Swift… Get over it! 😁)

Types of Dependency Injection

Constructor Injection – Requires all callers to supply the dependency as a parameter to the class’s constructor. See above example.

Property Injection – The consumer gets its dependency through a writable property that also has some default value. In iOS if you have used the delegate pattern, you have used this type of dependency injection.

Method Injection – Supplying the dependency as a method parameter. This would be used if your dependency can change for each method call like so:

Ambient Context – Makes your dependency available to every module without extra changes to your modules. This is typically done by creating a static property or method that could be called anywhere in your code. This should rarely ever be used. Where it might make sense is to use it on a cross-cutting concern like calling your logging framework so that you don’t have to inject your logging dependency into *EVERY* initializer which would pollute every API.

Now that you’ve seen the different kinds of dependency injection let’s talk about the concept of the composition root.

Composition Root

I first saw this idea of a composition root from Mark Seemann (See a theme? 😎) Mark describes it as:

A Composition Root is a (preferably) unique location in an application where modules are composed together.

But what does it mean?

What it means for iOS developers is that if you want to follow this kind of pattern, you should wire up all of your dependencies at startup in your AppDelegate. This way there is only one place in the code you need to look at to figure out your dependencies as opposed to having it spread out all over your project.

ZombieInjection’s Composition Root

In my project, the Composition Root is setup using the excellent Dip framework like so:

First, configure all of my dependencies in the DependencyContainer provided by Dip.

Second, call the configure method in my AppDelegate to actually do the configuration:

What this ended up meaning is that my main view model had to end up holding all of the dependencies and then sending them into lower view models via constructor injection. Here is what this looks like:

The flow goes like this… The ZombieListViewController is instantiated in the AppDelegate and then sets the dependencies on the ZombieListViewModel once the ZombieListViewController is done being created. The ZombieListViewModel then is holding references to these objects to send to lower screens, like ZombieDetailViewController.

For small applications this seems to work fine as there are not too many dependencies. You are then probably wondering… What about big applications!? Do I really want to carry all of these dependencies if I’m not sure if they’ll even be used?

Cue Sadness

In .NET, a solution could be to set up your dependency variables as lazily loaded so that they can be created only when they are needed, however that will not work here as I’ve implemented this solution using protocol oriented programming. Swift requires your variables to have initializers, i.e. you can’t put the keyword lazy in front of a Protocol property or you will get a compiler error. So at this point, until the Swift generics system gets better, your only option is to create all of these dependencies up front and pass them through or don’t use a Composition Root.

Conclusion

Even with some of the limitations of Swift’s generics system, I still love using Dependency Injection as much as possible. It truly does end up in code that is much more loosely coupled and much more testable. For the time being, you could use something like the Service-Locator Pattern (Full disclosure many see this as an anti-pattern) or something else to get around this limitation. I plan on engaging the Swift Evolution thread to see if this is something that will happen later on and will update if I create or come across a specific proposal that covers this.

Credit: Banner image adapted from one found at nearsoft’s “Dependency Injection in AngularJS”

Swift: The Churn

It has been an interesting experience for me to follow what the Swift community has been up to over the last few months. I’ve been excited to see them slowly adding and discussing features that I grew to love using in C# and have sorely missed while using Swift — things like async/await and much of the Generics Manifesto. These are the kinds of features that will finally move Swift ahead of Objective-C for your everyday iOS developer. With that said, I’ve been having a reoccurring question in the back of my mind…

An Honest Question

Sometimes I feel the need to ask basic, borderline silly questions at the risk of looking like a complete moron. Typically, this need arises when I can’t find the answers to these seemingly simple questions or I get the feeling that no one has asked the question yet. To make matters worse, these kinds of questions are often inflammatory! They typically call in to question a lot of hard work and progress that is being done on something — That is not the intent of the question. The intent of the question is to better understand why something is happening and what we can do better.

This question did not come to me until I listened to a recent podcast discussing “The Churn” as described in Uncle Bob Martin’s blog post: The Churn. As I read the post, I could not help but think of all the effort I’ve put into learning Swift over the past few months. This particular exchange from the post stood out to me:

Yet every time a new language comes along we dash away from those powerful tools to use the NEXT NEW THING. And the tools for that new language are like programming in the third world. God, you often don’t even have a reasonable rename refactoring!

It takes time to build up a reasonable toolset. If we keep on switching languages, we’ll never be able to tool those languages up.

>> But the newer languages are better.

Oh bull! They’re different; but they aren’t better. Or at least not better enough to justify throwing our toolset back into the stone age.

And think of the training costs for adopting a new language. Think of the cost to the organization of having to use 84 different languages because the programmers get excited about shiny new things every two weeks.

At this point you might be anticipating my question as something along the lines of —  Why not just put all this effort into Objective-C and stop with these Swift shenanigans?

super-troopers-shenanigans-o

That is not my question. To preface my actual question, I should mention that as a developer who is fairly new to native iOS work, I am not a big fan of Objective-C. I don’t like it’s syntax or structure. I personally believe that those are two big reasons as to why Swift even exists. Swift is much easier for new developers to understand and develop with and will allow current developers to be even more productive.

No my friends, my question is much more inflammatory than that. My question is: Why didn’t Apple just use C# instead of Swift? *Gasp*

jimcarrey_shocked

Yes… I went there. On the surface it seems completely ludicrous to ask why Apple didn’t adopt a language heavily tied to the Microsoft technology stack; however, if you dig a little deeper I think it’s a completely fair question to ask.

Digging Deeper

Below are the top 5 points I could think of as to why C# could have been a good option for Apple to build on:

1.  Xamarin is already doing this!

Yes it’s true. Xamarin takes C# code and compiles it down to ARM assembly code. For all intents and purposes, the code ends up being native iOS/Mac code. The main point here being that if a 3rd party vendor can do it, Apple could surely do it.

2.  Many problems with Swift are already solved in C#

There are a number of limitations in Swift presently that are actively being worked on by the community. I have great faith that these limitations will be taken care of in the not to distant future; but they could have been building on a platform that already has many of these problems solved. Things like a robust generics system, async/await, and most of the things in the Generics Manifesto come to mind.

3. Visual Studio

I’m sorry but Xcode isn’t even in the same league as Visual Studio. Xcode doesn’t even have the ability to refactor Swift code (See Uncle Bob’s exchange above)! Visual Studio is a fantastic IDE that can certainly make developers more productive. I know Visual Studio is not yet available on the Mac but Microsoft has been making great strides to bring Visual Studio-like experiences to multiple platforms. Even if Visual Studio never comes to Mac, Apple could have built in support for the language in Xcode similar to what they are doing for Swift.

4. C# is open source and cross platform

A year before Apple made Swift open source, Microsoft open sourced C# and the .NET Core. This is no longer a Microsoft proprietary language. At this point, Microsoft has the .NET Core running on Mac, Linux, and Windows. The ability to write your app and server side code in the same language would be amazing for Swift developers! This is already happening for C# developers… And yes — it’s awesome.

And that brings us to my last point:

5. Robust dependency/package management

If you’ve spent any significant time around NuGet, trying to use anything like the Swift Package Manager feels like being in a 3rd world country — It is a mess right now. It’s not integrated with Xcode and has lots of manual configuration that is hard to understand and hard to set up properly. It has a long, long way to go. Even CocoaPods and Carthage can also be annoying to use. If Apple had used C# they could have adopted NuGet and started with a mature package management system from the get-go.

Summary

I have thoroughly enjoyed learning Swift up to this point and will continue to do so going forward. I really do believe that at this point Swift is the the best way to do iOS/Mac development since the ship has essentially sailed. With that said, I am a little sad thinking about what could have been. If I take a step back and compare Swift to C#, Java, or others, I have a hard time nailing down what exactly Swift brings to the table that’s moving computer science forward as a whole. Often times while developing in Swift I feel like I am just using a more limited and opinionated version of C#. It will surely aid iOS/Mac developers, but it will do so at the cost of creating yet another wheel when there were many different wheels that could have been built on top of.

Zombie Injection: Applying (C)Sharp Thinking to Swift

Introducing ZombieInjection

Using C# and .NET thinking, ZombieInjection is a simple iOS app that shows a list of zombies in which you can select one and change its name on a detail screen. The name change then persists back to the list view. For this exercise, I tried to pick a small enough scope while still having enough meat to provide a useful exercise. And let’s be honest, zombies love meat!

I have spent the last couple weeks trying to reconcile my far deeper knowledge of C# with what I’ve been learning of Swift. It has not been very easy. Swift is just similar enough to C# that I get confused when I can’t implement certain features I was used to having in the .NET world.

The final result of this exercise is not perfect, but I am actually pretty happy with it. I will get into some of the more technical details and challenges in some future posts, but for right now I wanted to discuss this example at a high level. You can find the entire project here.

The “Right” Way

Before we get too far into the specifics, there is something you need to know about me, personally, that will help you understand some of the design decisions made:  I am always looking for the “right” way to do software development (sometimes to a fault). I’m fully aware that there is no “right” way to create software, but I think we can all agree someways are better than others. The main thing all programming languages share is purists yelling at each other; that is not what I’m trying to accomplish here.

wrong

It is not atypical for me to spend a lot of time researching new languages and new technologies to figure out how the experts do it. What I’m applying here is the result of all of those learnings I had in the C#/Xamarin world and combining them with what I’m learning in Swift/iOS. In my prior experience, I found many, many resources on how to write sustainable and testable software. Right or wrong, that kind of onus does not appear to get put on iOS app development. Yes, yes, I completely understand the fact that my iOS app will probably not be around in twenty years, but I would still like to write it as robustly as possible. To that end, you will probably see many places in this example project where I could have taken a much easier route — Please keep in mind that my goal was to figure out a scalable design that I could apply to big and small projects alike.

Acronym Soup

Prepare yourself — you are going to be hit by a lot of acronyms. In the construction of this app I used MVVM, DI, and IoC (and probably more!) Let’s define these ideas:

MVVM

MVVM stands for Model-View-ViewModel. This design pattern comes out of the Microsoft .NET world. You can find more on this pattern here. Here is an illustration of the preferred interaction between the components of the pattern:

MVVMPattern

While listening to many iOS podcasts, it sounds like this pattern is starting to get some traction in the iOS world. I think it is being used a little differently than expected on the iOS side, but that’s fine as I think the main idea of abstracting out your business logic is still the same.

In the .NET world, data binding is a big part of what the ViewModel does. As many of you are aware, iOS does not really do any kind of data binding out of the box. I love data binding to get rid of a lot of boilerplate code so I’ve implemented my example project using the excellent SwiftBond library. With that in place, I was able to write more condensed code and do away with all of the UI element setup code.

Generally, my goal for each ViewController is to boil it down as much as possible. For instance, here is what my detail view controller looks like:

The rest of the actual business logic is buried in the ViewModel (which gets injected when the ViewController is created). This approach leads to much lighter view controllers and the ability to properly unit test your business logic independent of UI code.

DI and IoC

DI stands for Dependency Injection. IoC stands for Inversion of Control. These concepts were initially very hard for me to wrap my head around but now I love them.

Love.gif

They make mocking in unit testing so much easier. I used the Dip framework by AliSoftware to implement these concepts. The main idea here is to use dependency injection, an IoC container, and protocol-oriented programming in conjunction with generics to get you to the point where there is only one place in your code that you are defining all of your concrete dependencies — called the Composition Root. If done right, you end up with one place where you need to define the concrete types; this allows for much easier mocking and stubbing in your unit tests. To learn more, take a look at the excellent book Dependency Injection in .NET by Mark Seemann.

I wrote a more in-depth post about this here.

Services and Repositories

The other architecture patterns I loved from the .NET world were the use of Services and Repositories to abstract where your data is being stored and how you interact with your different data objects. For example, in my project I have a ZombieService which conforms to ZombieServiceProtocol and within that ZombieService there is a Repository of Zombies. For the purpose of this example project, I just create 100 zombies at the start time of the app but you could easily connect this to a web service that is actually persisting your zombie list up in the cloud. The main benefit of doing all this work is that I can then create a ZombieServiceMock and a ZombieRepositoryMock to easily implement all of my unit testing without having a real database be part of the unit tests. To accomplish that, I created a DataServiceProtocol that defines all of the CRUD operations you can do to your zombies which then allows me to easily swap out my underlying database whenever I like.

Soap Box: You may have heard talks given where the point is made that no one ever swaps out their database so database abstraction is a waste of time. Do you know where EVERYONE should be swapping out their database? When you are unit testing!!!

Lastly, the other service I created was an ImageDownloadService which basically wraps around using AlamoFireImage. That allows for easier unit testing and the flexibility to swap out AlamofireImage for something else in the future if needed.

Summary

My main goal was to be able to put together a simple project that would allow me to exercise and incorporate many of the robust programming paradigms that I used in the .NET world. For many of you this may seem like overhead, but in my current role we need to create our iOS apps as robustly as possible and I think I managed to find a fairly good solution for the time being. If you you’ve made it down this far and you have some thoughts or questions, I would love to hear them!

P.S. Special thanks to Tyler Longren who runs the placezombie.com website which serves up the zombie placeholder images.