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.
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.
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?
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.
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.
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.
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.
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.
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.
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.