Mastering MVVM With Swift

Episode 1

Welcome to Mastering MVVM With Swift

Welcome to Mastering MVVM With Swift. In this series, you learn the ins and outs of the Model-View-ViewModel pattern. The goal is to provide you with the ingredients you need to implement the Model-View-ViewModel pattern in your own projects.

Episode 2

Is MVC Dead

Model-View-Controller, or MVC for short, is a widely used design pattern for architecting software applications. Cocoa applications are centered around the Model-View-Controller pattern and many of Apple's frameworks make heavy use of the Model-View-Controller pattern.

Episode 3

How Does MVVM Work

In this episode, we take a closer look at the internals of the Model-View-ViewModel pattern. We explore what MVVM is and how it works.

Episode 4

Meet Cloudy

In the remainder of this series, we're going to refactor an application that's built with MVC and make it adopt MVVM instead. This will give you two important insights. What are the shortcomings of MVC? How can MVVM help resolve these shortcomings?

Episode 5

What Is Wrong With Cloudy

Now that you have an idea of the ins and outs of Cloudy, I'd like to take a few minutes to highlight some of Cloudy's issues. Keep in mind that Cloudy is a small project. The problems we're going to fix with the Model-View-ViewModel pattern are less apparent, which is why I'd like to highlight them before we fix them.

Episode 6

A Quick Recap

Before you create your first view model, I want to revisit the internals of the Model-View-ViewModel pattern. We need to keep the following in mind. The model is owned by the view model. The controller doesn't know about and cannot access the model. The controller owns the view model. And the view model doesn't know about the controller it's owned by.

Episode 7

Time to Create a View Model

In this episode, we create a view model for the day view controller. Open Cloudy in Xcode and create a new group, View Models, in the Weather View Controllers group. I prefer to keep the view models close to the view controllers in which they're used.

Episode 8

Put the View Model to Work

If you're not sure how the various pieces of the Model-View-ViewModel pattern fit together, then this episode is certainly going to help. In this episode, we put the DayViewViewModel we created in the previous episode to work. This means we need to refactor the day view controller and the root view controller.

Episode 9

Rinse and Repeat

To adopt the Model-View-ViewModel pattern in the WeekViewController class, we first need to create a new view model. Create a new file in the View Models group and name the file WeekViewViewModel.swift.

Episode 10

Using MVVM In the Settings View

The Model-View-ViewModel pattern isn't only useful for populating data-driven user interfaces. In this episode, I want to show you how you can apply the Model-View-ViewModel pattern in the settings view controller.

Episode 11

Adding Protocols to the Mix

After we implemented the Model-View-ViewModel pattern in the settings view controller, we noticed we were repeating ourselves in the tableView(_:cellForRowAt:) method. We can solve this problem with a pinch of protocol-oriented programming.

Episode 12

Making Table View Cells Autoconfigurable

I don't know if autoconfigurable can be found in the dictionary, but I'm going to use it anyway because it best describes what we're going to do in this episode. In the previous episode, we refactored the SettingsViewController class. In the tableView(_:cellForRowAt:) method, we create an instance of type SettingsRepresentable?. The view controller manually configures each table view cell, using a view model. But why can't the table view cell take care of its own configuration?

Episode 13

Supercharging MVVM With Protocols

Let's apply what we learned in the previous episodes to the week view controller. The week view controller currently configures the cells of its table view. That's something we want to change. The refactoring of the week view controller involves four steps. We create a view model for each table view cell. The WeekViewViewModel generates a view model for each table view cell. We define a protocol which the view models for the table view cells conform to. The WeatherDayTableViewCell is able to configure itself using a view model.

Episode 14

Ready, Set, Test

Because we moved a fair bit of logic from the view controllers of the project into the view models, we gained an important advantage, improved testability. As I mentioned earlier, unit testing view controllers is known to be difficult. View models, however, are easy to test. And that's what I'll show you in the next few episodes.

Episode 15

Testing Your First View Model

In this episode, we test the view models of the settings view controller. We start with the SettingsViewTimeViewModel struct. Create a new file in the Test Cases group we created in the previous episode and choose the Unit Test Case Class template.

Episode 16

Using Stubs for Better Unit Tests

Testing the DayViewViewModel struct isn't very different from testing the view models of the SettingsViewController class. The only tricky aspect is instantiating a DayViewViewModel instance in a unit test.

Episode 17

A Few More Unit Tests

Writing units tests for the view models of the WeekViewController class is just as easy as writing unit tests for the DayViewViewModel struct. We start with the unit tests for the WeekViewViewModel struct.

Episode 18

Taking MVVM to the Next Level

You should now have a good understanding of what MVVM is and how it can be used to cure some of the problems MVC suffers from. But we can do better. Up until now, data in the application has flown in one direction. The view controller asks the view model for data and populates the view it manages. This is fine and many projects can greatly benefit from this implementation of the Model-View-ViewModel pattern.

Episode 19

What Are the Options

The question we need to answer in the next few episodes is "How can we tie everything together?" This is a problem many developers new to the Model-View-ViewModel pattern struggle with. It's not difficult to use the Model-View-ViewModel pattern to push data from the controller layer to the view layer. We've already covered that extensively in this series. But how do you respond to user interactions or changes of the environment, and update the user interface? Automatically.

Episode 20

DIY Bindings

Before we use RxSwift to implement the Model-View-ViewModel pattern, I want to show you how you can use closures to implement a custom solution. I usually refer to this solution as "DIY bindings" or "Do It Yourself bindings".

Episode 21

Refactoring the Add Location View Controller

It's time to refactor the AddLocationViewController class. We start by removing any references to the Core Location framework, including the geocoder property, the geocode(addressString:) method, and the processResponse(withPlacemarks:error:) method.

Episode 22

Why RxSwift

Before we refactor the AddLocationViewViewModel class, I'd like to take a few minutes to explain my motivation for using RxSwift and RxCocoa. There are several reasons.

Episode 23

Integrating RxSwift and RxCocoa

There are several options to integrate RxSwift and RxCocoa into a project. The README of the RxSwift project shows you the different possibilities. I mostly use CocoaPods and that's the approach I take in this series. If you'd like to follow along with me, make sure you have CocoaPods installed. You can find more information about installing CocoaPods on the CocoaPods website.

Episode 24

Refactoring the View Model

Make sure you open the workspace CocoaPods created for us in the previous episode. Open AddLocationViewViewModel.swift and add an import statement for RxSwift and RxCocoa at the top.

Episode 26

Protocol Oriented Programming and Dependency Injection

If we want to test the AddLocationViewViewModel class, we need the ability to stub the responses of the geocoding requests we make to Apple's location services. Only then can we write fast and reliable unit tests. Being in control of your environment is essential if your goal is creating a robust test suite.

Episode 27

Testing and Mocking

It's time to unit test the AddLocationViewViewModel class. Create a new unit test case class in the Test Cases group of the CloudyTests target and name it AddLocationViewViewModelTests.swift.

Episode 28

Where to Go From Here

You've reached the end of the series and you should now have a good understanding of the Model-View-ViewModel pattern and how it compares to the Model-View-Controller pattern. In this series, we refactored Cloudy. We transitioned the project from the Model-View-Controller pattern to the Model-View-ViewModel pattern. But what did we gain? Was it worth the effort?