Introducing Swift Action Delegate pattern Part 2
clacla
Here you find the Part 1 of this article.
A while ago I wrote an article which introduced what I called Swift Action Delegate pattern. It is an attempt to write less boilerplate code while implementing delegation for objects communication.
This was the core (maybe re-read the original article for more context):
protocol DelegateAction {}
protocol ActionDelegate: class {
func actionSender(_ sender: Any, didReceiveAction action: DelegateAction)
}
Few ex-collegues gave me an interesting piece of feedback. The sender is Any
type. This is a code smell and not following the Swift principles. We should send an actual type instead, avoiding casting.
Yesterday, I finally figured out how to solve this problem:
protocol DelegateAction {}
protocol ActionDelegate: class {
func actionSender(didReceiveAction action: DelegateAction)
}
We just remove the sender
from the function and pass it as part of the DelegateAction
payload. If DelegateAction
is an enum (as I generally suggest) it can simply be another parameter of its cases.
final class RedViewController: UIViewController {
enum Action: DelegateAction {
case close(sender: RedViewController)
case complete(sender: RedViewController, success: Bool)
}
weak var delegate: ActionDelegate?
func pressButton(sender: Any) {
delegate?.actionSender(didReceiveAction: Action.close(sender: self))
}
}
And the class which conforms to the ActionDelegate
protocol, has access to the sender which is of the actual type, not a simple Any
type.
final class ParentViewController: UIViewController, ActionDelegate {
func actionSender(didReceiveAction action: DelegateAction) {
switch action {
case RedViewController.Action.close(let sender):
print("Close red. Sender: \(sender)")
case RedViewController.Action.complete(let sender, let success):
print("Complete red. Sender: \(sender). Success: \(success)")
default:
print(action)
}
}
}
I think this makes the ActionDelegate
pattern stronger than it used to be.
As always, I am curious to get your opinion and feedback.