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 idea is simple. The view models for each of the sections of the table view are very similar and the computed properties the view controller accesses have the same name. This means we can create a protocol with an interface identical to those of the view models. Let me show you what I mean.
Creating the Protocol
Create a new group in the Settings View Controller group and name it Protocols. I prefer to keep protocols that are very specific close to where they’re used. But that’s just a personal preference.
Create a Swift file and name it SettingsRepresentable.swift.
Replace the import statement for Foundation with an import statement for UIKit and declare the SettingsRepresentable protocol.
SettingsRepresentable.swift
The protocol declares two properties, text of type String and accessoryType of type UITableViewCellAccessoryType.
SettingsRepresentable.swift
Conforming to the Protocol
The next step is surprisingly easy. Because the three view models implicitly conform to the SettingsRepresentable protocol, we only need to make their conformance to the protocol explicit. We use an extension to accomplish this.
SettingsViewTimeViewModel.swift
SettingsViewUnitsViewModel.swift
SettingsViewTemperatureViewModel.swift
Are you wondering why the extension is empty? We only use the extension to make the conformance of the view models to the SettingsRepresentable protocol explicit. There’s no need to implement the text and accessoryType properties of the protocol since the view models already implement these properties. This is important to understand.
Refactoring the Settings View Controller
It’s time to update the SettingsViewController class. Open SettingsViewController.swift and navigate to the tableView(_:cellForRowAt:) method. Before entering the switch statement, we declare a variable, viewModel, of type SettingsRepresentable?.
SettingsViewController.swift
We set the value of this variable in the switch statement. We can remove the configuration of the table view cell from the switch statement and move it to the bottom of the implementation of the tableView(_:cellForRowAt:) method. That’s a first step in the right direction.
SettingsViewController.swift
Protocols work very well with the Model-View-ViewModel pattern. In the next chapter, we take it one step further.