Lightweight Design Patterns in iOS (Part 2) - Presenter
Table of Contents
Lightweight Design Patterns in iOS (Part 2) - Presenter
Table of Contents
Design Patterns are part of Mobile Development for a while now and a revolution towards Quality Assurance is on. Such patterns have become a standard among the community, yet implementing an academic one might come with a price β complexity.
Because some Design Patterns solve very complex problems, they often result in a complicated implementation as well. So complex sometimes, that we tend to use heavy Third Party Frameworks, even for simple use cases.
The time has come to combine quality and simplicity.
π¬ Hi there, Iβm Jean!
Previously on the series Lightweight Design Patterns in iOS, we have covered the case of the Observer Pattern and how to make it feel like RxSwift! π
In this episode, we will take a quick look at the Presenter Pattern, the problems it solves as well as how to implement it in a simple and yet powerful manner! πΊ
A Presenter is simply an independent layer of an architecture, which can show a View from anywhere in the application. π
In iOS, this means an independent class or struct able to present a ViewController on its own. π
The practical way to present a ViewController is to have an extension on UIViewController to make use of the present(viewController:) method. π―
If we now look at an example, letβs say: present an Alert with an Error description, it would look pretty simple. π
extension UIViewController {
func present(error: Error, animated: Bool, completion: (() -> Void)? = nil) {
let alertController = UIAlertController(
title: "Error",
message: error.localizedDescription,
preferredStyle: .alert
)
let alertAction = UIAlertAction(
title: "Ok",
style: .default
)
alertController.addAction(alertAction)
present(alertController, animated: animated, completion: completion)
}
}
Though it might seem elegant at first, it actually comes with a price: every single ViewController is now able to present an Alert with an Error description. π²
Do we really want that? Or would we rather delegate this logic to an other independent layer? π€
You know where Iβm goingβ¦ π
Using a Presenter, we implement a separate entity responsible for presenting a View. This means for us, a struct! π
In the example of presenting an Error, we would implement an ErrorPresenter struct with the actual error as property and the present(in viewController:) function. β
struct ErrorPresenter {
let error: Error
func present(in viewController: UIViewController, animated: Bool, completion: (() -> Void)? = nil) {
let alertController = UIAlertController(
title: "Error",
message: error.localizedDescription,
preferredStyle: .alert
)
let alertAction = UIAlertAction(
title: "Ok",
style: .default
)
alertController.addAction(alertAction)
viewController.present(alertController, animated: animated, completion: completion)
}
}
And thatβs all, we now have a completely independent Presenter, that can be called from anywhere in our App! π
Calling our ErrorPresenter is as simple as it is elegant! π
let presenter = ErrorPresenter(error: NetworkError())
presenter.present(in: self, animated: true)
And boom! π₯
We just made a lightweight Presenter! π
Worth it? Did that help you see what problems the Presenter Pattern is trying to solve? How to make such a pattern lightweight?
If so, follow me on Twitter, Iβll be happy to answer any of your questions and youβll be the first one to know when a new article comes out! π
See you next week, for the Part 3 of my series Lightweight Design Patterns in iOS!
Bye bye! π