Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

iOS Delegation in iOS The Delegate Pattern Implementing A Delegate

Kapil Soni
Kapil Soni
2,612 Points

Totally confused with the example used.

It's hard to grasp with the lengthy code used to explain delegation

3 Answers

Jhoan Arango
Jhoan Arango
14,575 Points

Hello:

Yes, this can be confusing, especially if the explanation is so long and even more when it's being mixed with other things in there.

So here I will try to explain it to you the best way I can.

Delegation is when one object tells another object to do SOME things for it. It's as if I hired someone to come and clean my house. In that case, I will be delegating someone to do something for me.

Now let's look at this in code.

Let's say we have 2 objects:

Worker and Boss

The Boss is going to hire a worker and delegate some things for him to do. We also need a set of tools that the boss will provide to the worker. That tool will be our Protocol.

Let's create our set of Tools.

protocol SpecialToolBox {
    func drill()
    func hammer()
}

Now let's create a boss object wich has a property named "delegate" of type: SpecialToolBox.

struct Boss {

    // We want to make sure that whoever the delegate is can handle these tools.
    var delegate: SpecialToolBox? 

   // Here are the functions that the boss will be using to tell the delegate what to do.

    func saysStartDrilling(){
            delegate?.drill()
    }

    func saysStartHammering(){
            delegate?.hammer()
    }
}

Ok so now let's create that worker object that will conform to the protocol "SpecialToolBox", meaning that this worker is capable of handling these tools. So in other words, the worker will adopt all the functions that are in the protocol. Think of it as it's receiving the required tools to proceed with his job.

struct Worker: SpecialToolBox { // Conforms to the protocol

    var boss: Boss?

   // The tools from the SpecialToolBox
   // They have to be here to be able to conform to the protocol

    func drill() {
        print("Yes Sir I'm drilling")
    }

    func hammer() {
        print("Yes Sir I'm hammering")
    }
}

Now that we have our Worker and Boss, let's make them work.

let jhonTheWorker = Worker() // John The Worker
let boss = Boss(delegate: jhonTheWorker) // Kapil The Boss

// Boss tells the delegate what to do
boss.saysStartDrilling() // Prints " Yes Sir I'm drilling
boss.saysStartHammering() // Prints "Yes Sir I'm Hammering"

Notice that when initializing "Boss" we pass it the worker as his delegate. So Kapil the boss now has a delegate, and John the worker has a boss to work for.

Make sure to put this code in a playground to understand it better, if you need more help please let me know.

Good luck, I hope this helps.

Kapil Soni
Kapil Soni
2,612 Points

Hi Jhoan, That was a great example and very straightforward and well explained. My only query left is when you make struct called Worker and conform SpecialTookBox to it, in the body what was the necessity of creating variable boss of type Boss Struct ??

Kapil Soni
Kapil Soni
2,612 Points

Got it, Thanks for such beautiful clarification. I would request team Treehouse to amend the lesson with something simple as clarified by Jhoan.

Radu Albastroiu
Radu Albastroiu
17,498 Points

In this example we have a one to one relation. In the previous video we had 2 or 3 delegate objects and one boss. What is the proper way to implement this? Create the same number of bosses as there are delegate objects or make the boss support an array of delegate workers?

Jhoan Arango
Jhoan Arango
14,575 Points

You can have one boss to an array of delegates.

Kapil Soni
Kapil Soni
2,612 Points

Also, i found that optional used was not necessary and my code still runs and didn't complain.

Jhoan Arango
Jhoan Arango
14,575 Points

I'm not sure I understand your question correctly. But you do not have to make them structs, they can also be classes. And they are optional because the worker may or may not have a boss, or the boss may or may not have a delegate. So yes they should be Optional unless you make them explicit.

Kapil Soni
Kapil Soni
2,612 Points

Perfect "May and maynot have" reason for creating optional. The question what i wanted to know is below.

struct Worker: SpecialToolBox {

    var boss: Boss?

why is this variable boss created for in this context??

Jhoan Arango
Jhoan Arango
14,575 Points

A worker needs to have a boss, same as a boss needs to have a worker. So worker has to have this "boss" property to be able to become the delegate in this example. An object can become another's object delegate, but you must have some sort of reference to it otherwise, how would the worker know, who is his boss? who is he working for?. In a normal scenario, you may find something like this.

class ViewController: UIViewController, UITextFieldDelegate {


    @IBOutlet weak var textField: UITextField! // Reference

    override func viewDidLoad() {
        super.viewDidLoad()

        textField.delegate = self
    }

    func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        // Do something

        return true
    }
}

As you can see this is a ViewController class, it holds a reference to "textField", and it also adopts "UITextFieldDelegate", so this means that ViewController can now become the delegate for textField, and that's happening in viewDidLoad().

// Here we are saying : Me the ViewController will be the delegate for textField.
    override func viewDidLoad() {
        super.viewDidLoad()

        textField.delegate = self
    }

And now the ViewController performs all the task called by the textField.