0
1
00:00:00,970 --> 00:00:06,850
So, now that we've learned about the different ways that we can use name parameters in Swift functions,
1

2
00:00:07,240 --> 00:00:13,600
let's go ahead and modify our delegate method didUpdateWeather to be more in line with the way that
2

3
00:00:13,720 --> 00:00:15,800
Apple formats their delegate methods.
3

4
00:00:16,270 --> 00:00:23,320
So you can see that the first thing that by convention, we always have in a delegate method is the identity
4

5
00:00:23,470 --> 00:00:26,820
of the object that caused this delegate method.
5

6
00:00:26,830 --> 00:00:31,990
So in their case, it's the text field which triggers the textFieldDidEndEditing.
6

7
00:00:32,170 --> 00:00:37,630
And in our case, it would actually be the weatherManager that does this.
7

8
00:00:37,630 --> 00:00:46,100
So this is, obviously, going to be of data type WeatherManager and we can now separate out our two
8

9
00:00:46,190 --> 00:00:47,460
parameters.
9

10
00:00:47,570 --> 00:00:51,500
Now, notice how they actually have an emitted parameter name here,
10

11
00:00:51,530 --> 00:00:57,980
so we can do the same. And we can add an underscore here and remember to separate the underscore from
11

12
00:00:57,980 --> 00:01:06,680
the internal parameter name. And we, of course, have to update this in the protocol that defines how our
12

13
00:01:06,680 --> 00:01:08,450
delegate methods are meant to look.
13

14
00:01:08,450 --> 00:01:10,220
So let's update that here as well.
14

15
00:01:10,910 --> 00:01:17,240
So, now when we actually call this didUpdateWeather, you can see that it's telling us that we're missing
15

16
00:01:17,270 --> 00:01:21,320
the parameter for the first input which is the WeatherManager.
16

17
00:01:22,190 --> 00:01:28,280
So the weather manager is going to be "self," this current object, which is the one that triggered
17

18
00:01:28,340 --> 00:01:34,130
the didUpdateWeather and it's also the one that knows all about the current weather conditions and passes over
18

19
00:01:34,220 --> 00:01:36,840
this weather object.
19

20
00:01:37,140 --> 00:01:42,810
So by using these omitted parameter names, we can actually clean up a lot of our method names and make
20

21
00:01:42,810 --> 00:01:45,800
them more succinct and easier to understand.
21

22
00:01:45,900 --> 00:01:52,590
For example, when we say parseJSON and we're passing in a piece of weatherData, now that's quite useful
22

23
00:01:52,590 --> 00:01:58,040
within the function, especially when we want to actually use it to decode,
23

24
00:01:58,140 --> 00:02:05,430
but from outside the function, this is a little bit extraneous self.parseJSON weatherData: 
24

25
00:02:05,430 --> 00:02:06,360
safeData.
25

26
00:02:06,360 --> 00:02:13,890
I think it's entirely possible to omit that external argument and simply just have parseJSON with this
26

27
00:02:13,890 --> 00:02:22,370
particular data. And in other places, you'll see that Swift likes to use words from English that make
27

28
00:02:22,460 --> 00:02:28,850
the method names a lot more readable. For example, here where we've got performRequest (urlString:
28

29
00:02:28,850 --> 00:02:32,180
urlString) that feels a little bit extra as well.
29

30
00:02:32,540 --> 00:02:39,170
Instead, it would read a lot nicer and be more clear in English at least if we simply said performRequest
30

31
00:02:39,320 --> 00:02:41,140
with your urlString.
31

32
00:02:41,270 --> 00:02:46,360
So that method named now reads really nicely and when we call performRequest,
32

33
00:02:46,370 --> 00:02:51,980
we can say performRequest with: and then we pass in the urlString that we're going to perform the
33

34
00:02:51,980 --> 00:02:53,420
request with.
34

35
00:02:53,420 --> 00:02:59,660
These are all ways of making our code more readable, more easily understood by other programmers and
35

36
00:02:59,660 --> 00:03:02,690
also ourselves in the future.
36

37
00:03:02,690 --> 00:03:09,590
Now, with this in mind, I'm going to go ahead and add one other delegate method. And the delegate method
37

38
00:03:09,590 --> 00:03:14,540
is going to help us be able to pass errors out of our weather manager.
38

39
00:03:15,380 --> 00:03:22,730
I'm going to call the method didFailWithError and the input is going to be called error, and it's
39

40
00:03:22,730 --> 00:03:24,560
going to be of type Error.
40

41
00:03:25,790 --> 00:03:33,050
So, now we can trigger this delegate method whenever our code might fail in the WeatherManager, so that
41

42
00:03:33,050 --> 00:03:38,780
we can notify the delegate, "Hey, there's an issue here," so that we can pass this error out of our 
42

43
00:03:38,780 --> 00:03:43,130
WeatherManager. And a good place to do that is, for example, here,
43

44
00:03:43,400 --> 00:03:50,570
if during our networking session, we somehow, say, lost connection to the internet, went underground, some
44

45
00:03:50,570 --> 00:03:54,160
sort of issue there, then we'd probably end up with an error.
45

46
00:03:54,500 --> 00:04:02,240
So instead of printing it here, we can pass it back to the delegate by saying delegate.didFailWithError,
46

47
00:04:02,330 --> 00:04:10,070
and pass in the error object that's unwrapped. And, of course, because we're inside a closure,
47

48
00:04:10,070 --> 00:04:14,330
we have to add the word "self" in front to complete that line of code.
48

49
00:04:14,390 --> 00:04:23,930
Now, down here inside where we parse our JSON, we can also possibly fail when our data can actually
49

50
00:04:23,930 --> 00:04:25,930
be decoded successfully.
50

51
00:04:26,030 --> 00:04:31,510
Say, maybe we had an issue with the way that we constructed our weatherData or maybe, in fact, we got
51

52
00:04:31,510 --> 00:04:35,090
a JSON that doesn't even match this format that we've created.
52

53
00:04:36,320 --> 00:04:43,940
So in that case, we're going to catch the error and we can, again, call our delegate.didFailWithError,
53

54
00:04:43,970 --> 00:04:52,130
and we can pass in the error that we've caught. So, now back over in the WeatherViewController,
54

55
00:04:52,310 --> 00:05:01,030
we, of course, must implement this method didFailWithError and we can handle any errors that occur
55

56
00:05:01,390 --> 00:05:02,950
while using the WeatherManager.
56

57
00:05:03,310 --> 00:05:10,270
So the simplest way is to, of course, simply just print the error. But depending on what kind of errors
57

58
00:05:10,270 --> 00:05:14,940
you might get, you might want to relay some of that back to the user.
58

59
00:05:14,980 --> 00:05:22,240
Now, in my case, because the errors that were getting are "couldn't parse JSON," or networking errors, I don't
59

60
00:05:22,240 --> 00:05:25,750
think the user is going to understand what that's all about.
60

61
00:05:25,780 --> 00:05:31,030
So in fact, all that we're going to do is we're just going to print the error to the console. And during
61

62
00:05:31,030 --> 00:05:36,880
the testing of our app, say, we could switch off the Wi-Fi, switch off the 3G Internet, and see if we get
62

63
00:05:36,880 --> 00:05:41,040
any errors that gets printed. In the next lesson,
63

64
00:05:41,080 --> 00:05:43,930
we're going to update the weather that's being shown on the screen.
