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