Mastering MVVM With Swift

32 Episodes

Episode 1

03:25

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

07:20

Is the Model-View-Controller Pattern 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 4

07:46

Meet Cloudy

In the remainder of this series, we refactor an application that is built with the Model-View-Controller pattern and make it adopt the Model-View-ViewModel pattern instead. This will answer two important questions. (1) What are the shortcomings of the MVC pattern? (2) How can the MVVM pattern help resolve these shortcomings?

Episode 5

03:43

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

02:32

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 is owned by.

Episode 7

08:03

Time to Create a View Model

In this episode, we create a view model for the day view controller. Fire up Xcode and open the starter project of this episode. We start by creating 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 are used.

Episode 8

05:05

Put the View Model to Work

If you are not sure how the various pieces of the Model-View-ViewModel pattern fit together, then this episode will be helpful. In this episode, we put the DayViewModel struct we created in the previous episode to use. This means that we need to refactor the DayViewController and the RootViewController classes.

Episode 9

08:08

Rinse and Repeat

In this episode, we shift focus to the WeekViewController class. To adopt the Model-View-ViewModel pattern in the WeekViewController class, we start by creating a type for the view model of the week view controller. Create a new file in the View Models group and name the file WeekViewModel.swift.

Episode 10

06:56

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 show you how to apply the MVVM pattern in the SettingsViewController class.

Episode 11

04:05

Adding Protocols to the Mix

In the previous episode, I mentioned that we are repeating ourselves in the tableView(_:cellForRowAt:) method of the SettingsViewController class. We can resolve this problem with protocol-oriented programming.

Episode 13

06:26

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 is 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 WeekViewModel struct generates a view model for each table view cell. We define a protocol to which the view models for the table view cells conform. The WeatherDayTableViewCell class has the ability to configure itself using a view model.

Episode 14

02:47

Ready, Set, Test

Because we moved a fair bit of logic from the view controllers of the project to the view models, we gained an important advantage, improved testability. As I mentioned earlier in this series, unit testing view controllers is known to be difficult. View models, however, are easy to test and that is the focus of the next few episodes.

Episode 15

07:59

Testing Your First View Model

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

Episode 16

08:17

Using Stubs for Better Unit Tests

Unit testing the DayViewModel struct isn't very different from unit testing the view models of the SettingsViewController class. The only tricky aspect is creating a DayViewModel object in a unit test.

Episode 17

04:07

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 DayViewModel struct. We start with the unit tests for the WeekViewModel struct.

Episode 18

05:28

Taking MVVM to the Next Level

You should now have a good understanding of what the Model-View-ViewModel pattern is and how it can be used to cure some of the problems the Model-View-Controller pattern suffers from. We can do better, though. Data is currently flowing in one direction. The view controller asks its view model for data and populates the view it manages. This is fine and many projects can greatly benefit from this lightweight implementation of the Model-View-ViewModel pattern.

Episode 19

03:08

What Are the Options

How do we bind the various components of the Model-View-ViewModel pattern together? That is the question we focus on in the next few episodes. It is a problem most developers new to the MVVM pattern struggle with. It isn't difficult to use the Model-View-ViewModel pattern to push data from the controller layer to the view layer. We already covered that extensively in this series. What do we need to change to automatically update the user interface if the user interacts with the application or the environment changes?

Episode 20

08:21

DIY Bindings

Before we use RxSwift and Combine to improve the current implementation of the Model-View-ViewModel pattern, I want to show you how you can roll your own solution using closures. I like to refer to this solution as DIY bindings or Do It Yourself bindings.

Episode 21

05:01

Refactoring the Add Location View Controller

It is time to refactor the AddLocationViewController class. We start by removing any references to the Core Location framework, the import statement at the top, the geocoder property, the geocode(addressString:) method, and the processResponse(withPlacemarks:error:) method.

Episode 22

02:01

Why RxSwift

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

Episode 23

02:02

Integrating RxSwift and RxCocoa

There are several options to integrate RxSwift and RxCocoa into an Xcode project. The README of the RxSwift project shows you the different possibilities. I mostly use CocoaPods and that is the approach I take in this series. If you would 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

07:04

Refactoring the View Model Using RxSwift

With RxSwift and RxCocoa integrated into the project, it is time to refactor the AddLocationViewModel class. Make sure you open the workspace CocoaPods created for us in the previous episode. Open AddLocationViewModel.swift and add an import statement for RxSwift and RxCocoa at the top.

Episode 25

05:31

Refactoring the View Controller Using RxSwift

The changes we made in the previous episode broke the application. To fix what we broke, we need to update the implementation of the AddLocationViewController class. Open AddLocationViewController.swift and add an import statement for RxSwift and RxCocoa at the top.

Episode 26

03:51

Why Combine

RxSwift has been around for many years, but it isn't the only option you have. In 2019, Apple introduced Combine, a system framework that brings reactive programming to Apple's platforms. The framework provides a declarative API for processing values of time.

Episode 27

10:51

Refactoring the View Model Using Combine

Before we integrate the Combine framework into the project, I want to briefly revisit the RxSwift and RxCocoa integration. RxSwift is a reactive extension for the Swift language and, as the name suggests, RxCocoa reactifies the Cocoa components you use day in day out.

Episode 28

04:40

Refactoring the View Controller Using Combine

We put the foundation in place in the previous episode by refactoring the AddLocationViewModel class. We complete the integration with the Combine framework in this episode by refactoring the AddLocationViewController class.

Episode 29

07:22

Protocol Oriented Programming and Dependency Injection (RxSwift)

If we want to unit test the `AddLocationViewModel` 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 fast and robust test suite.

Episode 30

07:15

Protocol Oriented Programming and Dependency Injection (Combine)

If we want to unit test the AddLocationViewModel 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 fast and robust test suite.

Episode 31

08:28

Testing and Mocking (RxSwift)

It is time to unit test the AddLocationViewModel class. Create a new unit test case class in the Test Cases group of the CloudyTests target and name it AddLocationViewModelTests.swift.

Episode 32

09:08

Testing and Mocking (Combine)

It is time to unit test the AddLocationViewModel class. Create a new unit test case class in the Test Cases group of the CloudyTests target and name it AddLocationViewModelTests.swift.