If you have been reading or watching Cocoacasts for some time, then you know that the Model-View-ViewModel pattern is one of my preferred patterns for architecting applications. I have been using MVVM for several years in various projects and it continues to prove its value in every project I work on.
With this and the next episode, I want to make sure you choose for the Model-View-ViewModel pattern for the right reasons. I want to avoid that you adopt MVVM in a project because you were told it is a sound architecture or because you think you need view models if you use SwiftUI. In this episode, I want to highlight a few problems a typical SwiftUI application can suffer from. Those problems can be resolved by the Model-View-ViewModel pattern with relative ease.
In the previous episode, I highlighted a few problems a typical SwiftUI application can suffer from. These problems can be resolved in several ways. In this series, we explore how the Model-View-ViewModel pattern solves these problems. The goal is to put the views of the application on a diet and decouple view logic from business logic.
In the previous episode, we solved some of the problems we discussed earlier in this series. At the same time, we introduced a few code smells. We address those code smells in this episode.
Remember that a view should be dumb. It doesn't care what it displays. The notes view doesn't match that description. It can access the array of notes through its view model. That is a code smell and something we need to change. You learn how to do that in this episode.
In the past few episodes, you learned how the Model-View-ViewModel pattern can transform a project and its architecture. In the remainder of this series, we build an application from scratch. Through that process, you deepen your understanding of the MVVM pattern and how it affects a project's architecture, testability, and structure.
In this episode, we set up the project for Thunderstorm, the weather application we build in this series. We make a few changes to prepare the project for the MVVM pattern.
With the project set up, we can focus on adding features to the weather application we are building. In this episode, we populate the locations view.
In the previous episode, we wrote quite a bit of code that we wouldn't have written if we were building a SwiftUI application without the Model-View-ViewModel pattern. This is fine since we have laid a foundation we can take advantage of in the next few episodes. In this episode, we continue to build out the user interface of the locations view by displaying weather data.
In this episode, we implement the location view. The user can navigate to the location view by tapping a location in the locations view. The location view displays the current weather conditions at the top and a forecast at the bottom.
In this episode, we display weather data in the location view. Remember that the location view displays two subviews or child views, the current conditions view and the forecast view. These views are responsible for displaying the weather data for a location.
In this episode, we focus on the forecast view, a subview or child view of the location view. The forecast view displays the temperature for each day of the weather forecast. Let's add a few more details to the items of the vertical grid.
The locations view displays a static list of locations. While that has been useful to implement the user interface of the locations view, in the next few episodes we focus on adding locations.
In the next few episodes, we populate the AddLocationView. We break this task up into several smaller steps. We first populate the AddLocationView with stub data. Later in this series, we replace the stub data with data provided by the Core Location framework.
The AddLocationView displays stub data for the time being. We change that in this and the next episode by integrating the Core Location framework. Apple's Core Location framework defines an API for forward geocoding addresses. We use that API to convert an address to a collection of placemarks. The application converts the placemarks to Location objects the AddLocationView can display.
The GeocodingClient class returns stub data for the time being. In this episode, we integrate the Core Location framework and take advantage of the geocoding APIs it offers. We use the geocoding APIs to forward geocode the address the user enters in the TextField of the AddLocationView to a collection of `Location` objects.
In the previous episode, we made the Core Location framework a dependency of the project. That is fine, but we don't want a dependency to compromise the testability of the project. In this episode, we use a proven and familiar pattern to improve the testability of the GeocodingClient class.