Hey, guys, and welcome to another Deep Dive. In this deep dive, 1
we're going to be talking about the Delegate Design Pattern. 2
Now, you might be wondering, "Hey, wait a minute. 3
We just learned about the MVC, the model-view-controller design pattern and were already using it. 4
So why do we need to use another design pattern? 5
Well, remember that the definition for a design pattern is simply just a proven solution to a common 6
problem. 7
And while we're building our apps and programming, we come across lots of different problems, and they 8
often have different solutions. 9
So what exactly is the problem? 10
Well, let's say that you are Apple, and you're trying to design and create some template code, say, for 11
a UITextField, so that anybody who comes along and wants to build an iOS app, they don't have to define 12
from scratch all of the properties and methods for a UITextField because that would take forever. 13
Imagine having to define how a text field would look, whether it should have rounded corners, 14
what should happen when a user taps in it, detecting user touch, all sorts of things that would just end 15
up taking you years to create a single iOS app. So let's say that Apple creates this UITextField class 16
as a template for you to be able to use, 17
but then we come along and we decide to build a WeatherViewController. 18
Now, in our WeatherViewController, we need to be able to detect, 19
for example, let's say, we need to be able to know when the text field starts being edited by the user. 20
So we, somehow, need the text field to notify our WeatherViewController when it detects that editing 21
has begun. 22
So how would this actually work? 23
Well, then we would need to create in our UITextField the class definition for our UITextField 24
a WeatherViewController object which is created from the WeatherViewController class. 25
Well, then we could say weatherVC call your textFieldDidBeginEditing method, and that way we notify 26
our WeatherViewController and that method gets triggered for us to be able to do something in response 27
to this notification. 28
But you might be able to spot this quite a few problems here in our logic. Because if we are Apple and 29
we're creating this UITextField class and we somehow have to know about this WeatherViewController 30
which we never created, we know nothing about, and it's something that's going to be created in the future 31
by developers who are building apps using our UITextField. 32
Well, that's impossible to know, right? 33
And what do we do if we're trying to support loads of different classes that want to use the UITextField, 34
say, we had another class that wanted to be notified when the text field begins editing. 35
Are we going to create a new object from every possible class that's defined in the future by other 36
people? 37
How do we even do that? 38
So this is kind of the problem, right? 39
We want our text field to be maximally reusable. 40
And in order for it to do that, it can't know about any future custom classes that are created. 41
It has to somehow be able to let any class that uses it be able to know when it detects, for example, 42
the editing has begun, but it can't know the identity of these classes that uses it. 43
So what's the solution? 44
Well, one solution is the delegate pattern. And this is a pattern that Apple really likes to use, 45
which is why we're spending a lot of time to actually talk about it and try to understand it. Underlying 46
the delegate pattern, the technology that really makes it work is the protocol. 47
And we've already learned about protocols in the last lesson in our Swift Deep Dive. So we know that 48
we can create a protocol, say, in this case, we could create something called CanDealWithUITextFields, 49
and we can define in the protocol body some required methods. 50
So, for example, every class that says that it can deal with UI text fields should be able to implement 51
this method called textFieldDidBeginEditing. 52
So now a possible solution that we have using these protocols is, let's say, we still have the same situation, 53
our reusable UITextField that was created by Apple that doesn't know about any other class, 54
And we have our WeatherViewController which needs to use a UITextField and also need the UITextField 55
to tell it when the text field begins editing. 56
In this case, the protocol is actually called the UITextFieldDelegates. And we can make our 57
WeatherViewController be of that data type by adopting this protocol by adding it at the end of the class definition 58
like how we saw in the last lesson where we looked at how to adopt protocols. 59
So now that all WeatherViewController is able to deal with UITextFields, now that it's a UITextFieldDelegate, 60
we can now go in our UITextField and define one of its properties as a delegate property. 61
Now, this delegate property has a required data type. In order to set a class or a struct as the delegate 62
of the UITextField, it must conform to this UITextFieldDelegate protocol. So you must be of this 63
data type. 64
So just like in the last lesson, in order to be able to partake in the flyingDemo of the museum, you 65
had to be of the CanFly type. 66
In this case, in order to be the delegate of the text field, in order to be notified when certain things 67
in the text field changes, you must conform to this UITextFieldDelegate. And in the methods of the 68
UITextField, it might at some point when it detects the text field being interacted with, trigger a 69
method called textFieldDidBeginEditing. And it can safely call this method in the delegate because 70
it knows that in order for a class to have the type UITextFieldDelegate, it had to adopt this protocol. 71
And this protocol has the requirement of implementing this method textFieldDidBeginEditing. So therefore, 72
it could call delegate.textFieldBeginEditing not know about what class it is, what it inherits 73
from, what it does, who it is, what's its identity. It knows it can do this because it knows that it has to 74
be of this data type. So now in our WeatherViewController, in order to adopt this UITextFieldDelegate, 75
we have to have the required implementation for the textFieledDidBeginEditing. 76
So we have to be able to implement this method. Because some other class is going to trigger it somewhere 77
else. 78
Now, there's just one final piece of the puzzle. 79
How does the WeatherViewController actually sign up to be notified by the text field? 80
Well, our WeatherViewController needs to have a UI text field object. 81
So now that we have a new text field created from this reusable blueprint of a UITextField, we can 82
set its delegate as "self" which means its delegate is going to be equal to this current class, 83
the WeatherViewController 84
so now that we've got our UITextField, our WeatherViewController, and our UITextFieldDelegate all 85
defined so we can see what the code looks like, 86
let's see what happens when our app actually runs, what's the sequence of events. 87
Well, the first thing that happens is this line. 88
So we create a new text field from this reusable template of a UITextField. And so now we have this 89
reference to a UITextField, 90
next, we set that text field's delegate property as "self," as the WeatherViewController. 91
So now this property code delegate in the UITextField is now equal to our WeatherViewController. 92
And we can do this because our WeatherViewController adopts the UITextFieldDelegate, so it matches 93
this requirement for the delegate to be of this data type. 94
The next thing that happens is our text field, at some point the tags that the user has begun editing 95
in the text field, so it triggers this method which tells the delegates the text field has begun editing. 96
And this method gets called in the delegate which is, of course, currently, set as our WeatherViewController 97
which now triggers this method, so that we can do something when the user begins editing in the text 98
field. So now, through the power of protocols and the delegate pattern, we're able to switch out our 99
WeatherViewController with any other class, and it would work just as well as long as we're abiding by all 100
the rules and adopting the UITextFieldDelegate, 101
implementing the required methods, 102
we can always get notified when the text field did begin editing. And the best part of it is that the 103
UITextField doesn't have to change. 104
It doesn't need to know about this other class. 105
It doesn't need to know its identity. 106
It doesn't need to know what methods it has, what properties it has. 107
All it needs to know is that it conforms to the data type of the UITextFielddelegate protocol which 108
means that it's assured that whatever class it is has a method code TextFieldDidBeginEditing which 109
it can trigger by calling delegate.textFieldDidBeginEditing. 110
Now, this is how we were able to use our UITextField and were getting a peek under the hood. 111
But the shame is that because Apple's code, so UIKit, everything that, say, our UITextField, UILabel, 112
UIButtons, all of these components are proprietary Apple components which means that the code is not 113
open source. It's proprietary which means we can't actually see how the UITextField implements the 114
delegate or how does it trigger the delegate.textFieldDidBeginEditing. 115
So we're only seeing a part of the picture here 116
when we use the UITextField. So to be able to get an even deeper understanding of protocols and delegates, 117
let's create our own reusable class which has a delegate property and can trigger the delegate methods. 118
Let's see the entire picture by creating everything from scratch.