Set Up the MVP Types

Let’s set up the new types we need for MVP and the relationships between them.

We’ll continue where we left off with Chapter 18, Refactoring: Moving to MVVM. There’s no need to go through MVVM to get to MVP. But in our example, the responsibilities are clearer in the MVVM version, making it easier to work with. So duplicate the MVVM source code into a new folder named MVP. The project name will continue to be “Refactoring.”

We’ll start by setting up an empty View Commands protocol. Create a new file to hold a protocol named ChangePasswordViewCommands. Because the presenter’s reference to it will be unowned, let’s make it a class-only protocol to keep Swift happy:

MVP/Refactoring/ChangePasswordViewCommands.swift
 protocol​ ​ChangePasswordViewCommands​: ​AnyObject​ {
 }

Add an extension to ChangePasswordViewController to conform to this protocol:

MVP/Refactoring/ChangePasswordViewController.swift
 extension​ ​ChangePasswordViewController​: ​ChangePasswordViewCommands​ {
 }

Next, define ChangePasswordPresenter. It receives a ChangePasswordViewCommands implementor as its first initializer argument. (There will be more arguments later.) Hold on to it using an unowned property:

MVP/Refactoring/ChangePasswordPresenter.swift
 class​ ​ChangePasswordPresenter​ {
 private​ ​unowned​ ​var​ view: ​ChangePasswordViewCommands​!
 
 init​(view: ​ChangePasswordViewCommands​) {
 self​.view = view
  }
 }

Finally, add a property in ChangePasswordViewController to the presenter. We’re going to pass self as the argument, so we’ll delay construction of the property by making it a lazy property:

MVP/Refactoring/ChangePasswordViewController.swift
 private​ ​lazy​ ​var​ presenter = ​ChangePasswordPresenter​(view: ​self​)

Now we have a View Commands protocol, and the view controller conforms to it. The view controller has a presenter. And the presenter points back to the view controller through the protocol. The pieces are empty, but we have what we need to begin refactoring to MVP.