Chain of Responsibility Pattern in Swift

Chain of Responsibility Pattern in Swift example

Hoi mensen, Leo hier. Today’s topic is the Chain of Responsibility Pattern in Swift which is a behavioral design pattern that lets you send requests along a chain of handlers.

We will explore the responder chain design pattern that is responsible for all the touches going to the right views in iOS. When a user touches the screen it starts to hit test, in iOS is the responder chain pattern, to check what view is under the user’s finger.

For example, if your view hierarchy is ViewController -> UIView -> UITableView -> UITableViewCell, when the user touches the UITableViewCell if it does implement touchesBegan the action will be performed on it, otherwise it will go to the UITableView asking if it can respond to the touchesBegan and if not it will check UIView and so on.

The magic behind it all is that you don’t need to actively create the responder chain with your views, the UIKit framework will do that for you! It means that every time you add a subview or a child view controller, it automatically joins the chain.

Today you will create your very first Responder Chain and check how it can be simple and powerful. It’s not the scope of this article to explain the Chain of Responsibility pattern, others have already done it in a better way than I could, and we will only implement it in Swift.

Let’s code… but art first!

 

Painting of The Day

This painting is “Young mother with child” (1520-1529), it’s a masterpiece from Lucas Cranach the Elder. Was a German Renaissance painter and printmaker in woodcut and engraving, and was a court painter to the Electors of Saxony for most of his career.

He was a close friend of Martin Luther. Cranach also painted religious subjects, first in the Catholic tradition, and later trying to find new ways of conveying Lutheran religious concerns in art. He continued throughout his career to painting nude subjects drawn from mythology and religion.

The reason I choose the painting is that it has a lot of chains… Got it?

 

The Problem – Chain of Responsibility Pattern in Swift

You are asked to create a structure capable of responding to messages, but only the right receiver should respond to the input. For example, if you have an authentication and authorization system, you could just create a chain of everything you need to check, and after all, checks return to the caller true or false.

The first thing to do is to create the protocol. What it will look like? Well… there are some alternatives but all of them include at least two things: you need an optional reference to the next one in the chain and need the function that will handle the request.

The reference in the protocol must be optional because the root of the chain will have a nil parent. Do you still think that algorithms and data structure are just for college? What this pattern looks like?

The first version I’ll present here will work with three properties. I’ve added the action itself so we can filter what action we want.

First, create the enum of actions and the protocol in playgrounds:

enum ChainAction {
    case message
    case print
    case none
}

protocol Chainable {
    var parent: Chainable? { get set }
    func handle(on id: ChainAction, message: String)
}

With that set, you can implement the protocol, let’s imagine that you will create some responder to the ChainAction.message, you could do like this:

struct MessageChain: Chainable {
    
    var parent: Chainable?
    private let chainAction = ChainAction.message
    
    func handle(on id: ChainAction, message: String) {
        if id == chainAction {
            print("Handling [\(message)]","was handled at action {\(chainAction)}")
        } else {
            print("This chain type [\(chainAction)] can't handle: [\(id)] type")
            parent?.handle(on: id, message: message)
        }
    }
}

This wouldn’t be useful if we didn’t have any more implementations. So let’s do it:

struct DefaultChain: Chainable {
    
    private let chainAction = ChainAction.none
    var parent: Chainable?
    
    func handle(on id: ChainAction, message: String) {
        if id == chainAction {
            print("Handling [\(message)]","was handled at action {\(chainAction)}")
        } else {
            print("This chain type [\(chainAction)] can't handle: [\(id)] type")
            parent?.handle(on: id, message: message)
        }
    }
}

This can be as complex as you want. You could handle all the ChainActions or just one as in the example above. Or you could even execute some tasks and still pass the message to others in the chain, in this case, would something like the authorization and authentication system that I mentioned above. Use your creativity.

And to test all the code you just need to create the object with the right parents and call the handle in the leaf ( the last one of the chain…):

let c1 = DefaultChain(parent: nil)
let c2 = MessageChain(parent: c1)
let c3 = DefaultChain(parent: c2)

c3.handle(on: .message, message: "NEW MESSAGE")

This will result in:

Chain of Responsibility Pattern in Swift tutorial example

 

An Objective-C Chain of Responsibility Example

You can also use #selectors to perform the action that you want. This way you leave it to the old and good objective-c to handle the actions. This example is heavily inspired by the book Swift Design Patterns. Let’s try it out in the Playgrounds:

class Handler: NSObject, Handling {
    
    var next: Handler?
    
    init(next: Handler?) {
        self.next = next
    }
    
    func handle(selector: Selector) {
        if responds(to: selector) {
            perform(selector)
        } else {
            next?.handle(selector: selector)
        }
    }
}

class MessageHandler: Handler {
    @objc func handleChain() {
        print("Mission finished! We landed")
    }
}

let root = MessageHandler(next: nil)
let first = Handler(next: root)
let second = Handler(next: first)
let third = Handler(next: second)

let action = #selector(MessageHandler.handleChain)
third.handle(selector: action)

This should result:

second example of chain of responsibility pattern

And that’s it!

 

Summary – Chain of Responsibility Pattern in Swift

Today we implement the chain of responsibility pattern in Swift in two ways. The first one is a Switfier version and the second one is a more objective-c version. Both have the same principles and functionalities, you can pick whatever you find best OR could create an even better one! If you create your own please share it in the comments sections.

That’s all my people, I hope you liked reading this article as much as I enjoyed writing it. If you want to support this blog you can Buy Me a Coffee or leave a comment saying hello. You can also sponsor posts and I’m open to freelance writing! You can reach me on LinkedIn or Twitter and send me an e-mail through the contact page.

Thanks for reading and… That’s all folks.

Credits:

title image

Share this post:

Related posts

Featured

Sponsor