0
1
00:00:00,530 --> 00:00:06,410
Previously, I've challenged you to use the eggTimes dictionary to print out the hardness that was selected
1

2
00:00:06,410 --> 00:00:08,690
by the user. To solve this challenge,
2

3
00:00:08,690 --> 00:00:14,840
we will combine our knowledge of working with both dictionaries as well as optionals. In order to solve
3

4
00:00:14,840 --> 00:00:16,060
this challenge,
4

5
00:00:16,070 --> 00:00:25,280
all we had to do was simply, inside our print statement, add the eggTimes dictionary, and then use the
5

6
00:00:25,280 --> 00:00:32,960
square brackets to tap into the eggTime that we want depending on the hardness that was chosen by the
6

7
00:00:32,960 --> 00:00:34,130
user.
7

8
00:00:34,130 --> 00:00:41,750
So in this case, we know that our sender.currentTitle can only be one of three values: Soft, Medium,
8

9
00:00:41,990 --> 00:00:43,220
or Hard.
9

10
00:00:43,220 --> 00:00:51,320
So if we match these with the keys in our dictionary, then we'd be able to retrieve each of these values.
10

11
00:00:51,770 --> 00:00:59,300
So we could simply write eggTimes, and then we could add our hardness in here as the key.
11

12
00:00:59,300 --> 00:01:07,640
Now, even though our code seems to work, we get a error from Xcode. And it tells us that "Value of optional
12

13
00:01:07,640 --> 00:01:15,670
type 'String?' must be unwrapped to a value of type 'String,'" In order to solve this,
13

14
00:01:15,680 --> 00:01:18,890
they give us five ways of fixing it.
14

15
00:01:20,150 --> 00:01:28,390
And the reason is because the sender.currentTitle is something that is a bit of a unknown, right?
15

16
00:01:28,400 --> 00:01:35,420
You might have a button which triggers this IBAction where it doesn't actually have a title. Well, in
16

17
00:01:35,420 --> 00:01:39,710
which case, sender.currentTitle would be equal to nil.
17

18
00:01:39,740 --> 00:01:48,170
So then if you have a nil value that you put in here that you try to retrieve from your eggTime dictionary,
18

19
00:01:48,170 --> 00:01:51,500
well, then it doesn't know which one to give you, right?
19

20
00:01:51,500 --> 00:01:54,050
Nil is not Soft, Medium, or Hard,
20

21
00:01:54,140 --> 00:01:55,950
so then we end up with a error
21

22
00:01:55,960 --> 00:01:59,030
down the line and our app would crash.
22

23
00:01:59,030 --> 00:02:04,510
So to prevent this, the sender.currentTitle has a different data type.
23

24
00:02:04,970 --> 00:02:07,640
So you hold down option and you click on it,
24

25
00:02:07,640 --> 00:02:15,610
you can see that it's data type is a string question mark which is what we call an optional string.
25

26
00:02:15,740 --> 00:02:22,130
So the reason why it's optional is because you could have a button that doesn't, in fact, have 
26

27
00:02:22,130 --> 00:02:22,960
a currentTitle,
27

28
00:02:23,150 --> 00:02:29,840
so the currentTitle could legitimately not exist. But, of course, in order to use it inside our dictionary
28

29
00:02:30,170 --> 00:02:35,040
because all of our dictionary keys are, in fact, pretty solid strings, right?
29

30
00:02:35,060 --> 00:02:36,620
They're not optional strings.
30

31
00:02:37,040 --> 00:02:44,750
Well, then we have to convert this hardness which comes from sender.currentTitle into a nonoptional.
31

32
00:02:45,200 --> 00:02:47,630
One way of doing that, as you might have seen before
32

33
00:02:47,630 --> 00:02:55,530
when we use the code from StackOverflow to play sound, we added a exclamation mark at the end of
33

34
00:02:55,540 --> 00:03:04,260
sender.currentTitle. So this essentially says that "Yes, I am the human programmer. I know better than you,
34

35
00:03:04,270 --> 00:03:05,220
Xcode.
35

36
00:03:05,310 --> 00:03:12,660
I know that all three buttons which are linked to my IBAction, so all of the senders will always have
36

37
00:03:12,660 --> 00:03:15,180
a current title and this will never fail.
37

38
00:03:15,220 --> 00:03:16,800
It'll never crash in the future.
38

39
00:03:16,800 --> 00:03:18,270
Don't worry about it."
39

40
00:03:18,300 --> 00:03:25,860
So now if we go ahead and run our app, you can see that it actually lets us run the app because errors
40

41
00:03:25,860 --> 00:03:29,330
will stop the app from running, but warnings will not.
41

42
00:03:29,340 --> 00:03:36,060
So if we now click on each of our buttons, you can see that we get an optional printed.
42

43
00:03:36,330 --> 00:03:42,630
I know it seems like we just unwrapped the sender.currentTitle. So why are we seeing an optional again?
43

44
00:03:42,930 --> 00:03:47,580
Well, this optional doesn't have anything to do with sender.currentTitle,
44

45
00:03:47,580 --> 00:03:51,660
instead, it has something to do with how dictionaries work in Swift.
45

46
00:03:51,660 --> 00:03:52,850
Now why is that?
46

47
00:03:52,860 --> 00:03:56,380
Why are we getting an optional out of our dictionary?
47

48
00:03:56,400 --> 00:04:01,580
Well, our dictionary has keys which are of string data types.
48

49
00:04:01,650 --> 00:04:07,800
So let's say that we try to retrieve 5, the value 5 out of our eggTime dictionary.
49

50
00:04:07,800 --> 00:04:12,540
Well, I could simply provide the key "Soft," right?
50

51
00:04:12,840 --> 00:04:15,750
And when this is printed, we would get 5.
51

52
00:04:15,750 --> 00:04:19,920
But what if I had made a typo in this? Because it's a string, right,
52

53
00:04:19,920 --> 00:04:23,130
nobody's going to check whether 5 typed it correctly or not.
53

54
00:04:23,580 --> 00:04:30,870
Well, in that case, the soft with a lowercase "s" doesn't actually exist in this dictionary as a key.
54

55
00:04:30,870 --> 00:04:38,820
So then this result would end up being nil. So if I run this right now and if I press on any of the buttons,
55

56
00:04:39,270 --> 00:04:48,150
all I will get is nil because it can't find anything with the key "soft" in this eggTime dictionary.
56

57
00:04:48,150 --> 00:04:57,390
So that's why when you provide a key as a piece of text to retrieve an item out of a dictionary, the
57

58
00:04:57,480 --> 00:05:00,660
end result will be a optional.
58

59
00:05:00,660 --> 00:05:08,460
And I can show you that if I say, let result = eggTimes, and if I hold an option and click on result,
59

60
00:05:08,880 --> 00:05:13,320
you can see that the result is actually an optional integer.
60

61
00:05:13,320 --> 00:05:20,760
So it's trying to grab an integer out of our dictionary, but it doesn't know if we'll definitely be able
61

62
00:05:20,760 --> 00:05:22,650
to find one using this key.
62

63
00:05:22,890 --> 00:05:25,650
Then the result becomes an optional.
63

64
00:05:25,650 --> 00:05:32,350
So if we wanted to not be an optional, then we could, of course, hit the exclamation mark.
64

65
00:05:32,430 --> 00:05:39,660
And in fact, if we were using the hardness value which comes from our button titles, then we know that
65

66
00:05:39,660 --> 00:05:45,480
they are for sure spelt correctly because we can see them right here and we can match the spelling of
66

67
00:05:45,480 --> 00:05:49,620
the Soft, Medium, Hard with these three keys.
67

68
00:05:49,620 --> 00:05:54,630
So in that case, then we can be pretty sure that this result,
68

69
00:05:54,630 --> 00:06:00,000
so retrieving an item out of our dictionary is definitely not going to fail ever,
69

70
00:06:00,000 --> 00:06:03,050
then we can add an exclamation mark at the end.
70

71
00:06:03,330 --> 00:06:11,340
And if we now print our results which has been what we would call unwrapped, then you'll see that instead
71

72
00:06:11,340 --> 00:06:15,960
of getting an optional integer, we actually get a actual integer.
