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 Plus

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 Plus

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 Plus

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 Plus

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 Plus

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 Plus

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 Plus

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 Plus

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 Plus

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 Plus

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 Plus

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 Plus

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 Plus

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 Plus

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 Plus

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 Plus

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?