Simple MVP Design Pattern in Swift

McCallumDev
The Startup
Published in
3 min readJun 28, 2019

As part of my learning, I’ve been looking at different design patterns and architectures in Swift.

Most people when they start learning Swift, will be familiar with the MVC (Model View Controller) model, but this can quickly result in “Massive” ViewController files and can be restrictive when it comes to performing unit testing on the logic within the app.

An alternative to the “Massive”VC problem is to implement a MVP Model. MVP stands for Model View Presenter and is, at its core, an effective way to move much of the logic from your ViewController files and instead replace it with a call to a presenter. This means everything on your Presenter file is testable and easy to access and read.

This Simple, basic app will help us get set up using the MVP model. The functionality of the app is small, basically we have button and a label, when the button is tapped 5 times, the label will change (and so will the view’s background colour).

In a basic, single view project, I’ve set up the ViewController.swift file to look like this:

import UIKitclass ViewController: UIViewController {
lazy var presenter = Presenter(with: self)@IBOutlet weak var changeTextLabel: UILabel!override func viewDidLoad() { super.viewDidLoad()}@IBAction func tapMeButton(_ sender: Any) { presenter.buttonTapped()}}

That’s it! We give the ViewController access to a presenter, and once the view is loaded, we pass a reference of our “self” to the presenter. When the tapMeButton is tapped, we send a call to the presenter to say “Hey! I’ve been tapped! What should I do?”

Next, to the Presenter.swift file:

import Foundationprotocol PresenterView: class {    func updateLabel()}class Presenter {weak var view: PresenterView?// Pass something that conforms to PresenterViewinit(with view: PresenterView) {    self.view = view}var timesTapped = 0func buttonTapped() {    timesTapped += 1    if timesTapped >= 5 {    self.view?.updateLabel()}}}

Here I’ve written a PresenterView protocol method, which when subscribed to require’s an updateLabel() function, we’ll subscribe to this on the ViewController later and this is where we will tell the ViewController what to display to the user.

Next inside the Presenter class we set an optional view then initialise it with the PresenterView playing the roll of the view as any references to this, will be carried out on the ViewController once we subscribe to the protocol.

I’ve set a variable called timesTapped and set its initial value to 0. Next, I have a a buttonTapped() function, remember we called it before on the ViewController file? This increases the timesTapped value by one and once we have hit the button 5 times, we access the view(protocol) and call the updateLabel() Function.

Back to the ViewController file, I’ve added and extension of the ViewController class and conformed to the PresenterView Protocol:

extension ViewController: PresenterView {   func updateLabel() {   changeTextLabel.text = "I have been changed!"   self.view.backgroundColor = .yellow}}

This is where we make any UI changes, and manipulate the view. The end result looks like so:

This is just a very simple example of how the MVP Model works. Feel free to get in touch with suggestions or changes. Play about with it, add more UI elements to your VC and go crazy with the logic on your Presenter.

--

--