Implement Delegate pattern in Swift

While teaching iOS development in Swift at iOS Akademija (here in Belgrade, Serbia), one of the most challenging topics for students to grasp is Delegate pattern.

I’m not sure why that is; most likely due to loose coupling and very asynchronous nature of the relationships between the relevant parties. Which are the very strengths of the pattern but those multiple moving parts are certainly adding to complexity. It takes some time and experience to recognize the need and the place for the pattern and internalize its implementation.

Teaching approach I like to use is to find a corresponding real-world problem and then map it into the pattern. So…

Imagine a person lost its house Key thus needs a new one made.

Person does not care how keys are made. How long it takes (well, within common sense). What tools are needed etc.

It only knows how the Key looks like and needs someone to do it.

Person finds the Keymaker that makes such specific Key type.

Goes to the shop and

registers its contact information so Keymaker can make contact when job is done

agrees with Keymaker how it will know when it’s done, meaning how it will receive the Key

then waits for the call / delivery of the Key

Keymaker will make the Key in due time and when it’s ready, it

looks for the customer’s contact info

then calls customer and delivers the Key

This is perfect fit for the Delegate pattern. So let’s implement it in Swift.

First, as in all good apps, we need to create proper data model for the Key == a description of work that needs to be done.

struct Key {
var shape: String
}

Next, we need to model the Person, end user == the object that needs some work done.

final class Person {
var name: String = "Me"
var key: Key?
}

Lastly, let’s model the service which performs some function. Here Keymaker which makes the specific Key.

final class Keymaker {
weak var customer: Keymaking?
}

Property customer models registration point for end users that need this specific work — key of type Key — done. In most iOS APIs, you will see the name delegate being used here; which is the common name used when implementing Delegate pattern. But that’s just developers using the same property name as the pattern itself. The actual name of the property is irrelevant and you can use whatever you want.

Notice two things here:

customer is a singular item which implies the Keymaker can only work with one customer at the time. Thus it’s your job as developer to make sure that if one object assign itself as customer, no other object overrides or nullifies that assignment. Otherwise original Person will never receive its Key.

Keymaker does not care what is the real, actual type of the entity/object that needs the Key made. It’s not Person, Company nor anything concrete. It’s actually a special abstract type, declared by the Keymaker which describes what any customer needs to implement in order to work with the Service.

In Swift, that’s done through protocols, which represent output interface declared by the Service to describe how it will deliver the result of its work.

Note: this part is usually marked as (file)private for the Keymaker. No object outside the Keymaker should know nor care how the Key is produced.

Because you will usually have Key, Person and Keymaker all written in separate corresponding .swift files, then fileprivate helps Keymaker keep its trade secrets. Keymaker can change its internal process without fear that some nosy customer is trying to directly access parts of the Key making process. :)

I hope this was useful in understanding such crucial software design pattern. It’s very pervasive in iOS SDK thus any app developer needs to master it.

You will find it with UITextField which allows any other object conforming to UITextFieldDelegate protocol to control parts of its behavior and receive information when editing starts, stops etc.

UITableView uses it to offload input data to anyone implementing UITableViewDataSource. Through UITableViewDelegate it allows any other object to control parts of its look and behavior plus stay informed when something happens (i.e. row is selected).

Most importantly, Delegate pattern — along with Dependency Injection pattern — enables easy and straight-forward Composition of otherwise unrelated objects, views and controls. Mastering that technique places you well on the path to clean and easily maintainable code.