0
1
00:00:00,710 --> 00:00:05,000
Welcome to yet another Swift Deep Dive. In this episode,
1

2
00:00:05,000 --> 00:00:09,620
we're going to talk about Optionals (!?). And what the heck are "Optionals"?
2

3
00:00:09,620 --> 00:00:16,070
So we keep seeing these exclamation marks in question marks all over our code, especially when we find
3

4
00:00:16,070 --> 00:00:20,820
it from StackOverflow or when we see it in the Swift Documentation.
4

5
00:00:20,900 --> 00:00:25,270
Now what exactly does it mean and how do we use it?
5

6
00:00:25,310 --> 00:00:31,350
So in order to understand this better, I want to introduce you to our shed cat Fluffy.
6

7
00:00:31,370 --> 00:00:38,450
So this is our cat that we have to look after now, you and me. But we have to transport our cats and
7

8
00:00:38,450 --> 00:00:41,180
we're going to do that in a cardboard box.
8

9
00:00:41,210 --> 00:00:47,210
So Fluffy goes into the box and we're pretty sure that currently, we have definitely a real cat in the
9

10
00:00:47,210 --> 00:00:47,660
box.
10

11
00:00:47,710 --> 00:00:48,110
Meow.
11

12
00:00:48,530 --> 00:00:54,990
But let's say that during the hectic time of moving, we also accidentally popped a bottle of poison into
12

13
00:00:55,010 --> 00:00:56,960
the same box as Fluffy.
13

14
00:00:57,620 --> 00:01:06,200
So now we package it up and we kind of moved around in the van, shake it around, and the poison bottle
14

15
00:01:06,200 --> 00:01:11,090
might be broken. And we now basically have an optional cats,
15

16
00:01:11,120 --> 00:01:11,550
right?
16

17
00:01:11,570 --> 00:01:14,840
We have a cat with a question mark at the end of it.
17

18
00:01:14,840 --> 00:01:23,510
We don't know if Fluffy is dead or alive. And if we were to force open or force unwrap our box and see
18

19
00:01:23,510 --> 00:01:29,810
what's inside, well, we might discover that, indeed, we do still have Fluffy. She's alive and well and she's
19

20
00:01:29,810 --> 00:01:36,830
smart enough to not eat the poison because, you know, we're good at rearing cats. But we might also find
20

21
00:01:36,830 --> 00:01:39,110
that Fluffy is no more,
21

22
00:01:39,200 --> 00:01:43,310
she got tempted by the poison. It smelt like Play-Doh,
22

23
00:01:43,310 --> 00:01:46,820
so she had a little bit. And now Fluffy is dead.
23

24
00:01:46,820 --> 00:01:53,040
So we might actually have no cat, which in programming lingo, we would call nil.
24

25
00:01:53,090 --> 00:01:56,100
This is essentially how optionals work.
25

26
00:01:56,160 --> 00:02:00,110
There's frequently cases where you need a container,
26

27
00:02:00,140 --> 00:02:04,820
so a variable, that might often need to start out containing no data.
27

28
00:02:05,180 --> 00:02:11,090
Let's say that you had a field in your app where you were going to save the user's username. Well, before
28

29
00:02:11,090 --> 00:02:18,440
they actually created that username variable is going to be nil. But then, hopefully, at a later date,
29

30
00:02:18,500 --> 00:02:24,470
when you need to use the username to display it on screen or to use it in some way, then you're hoping
30

31
00:02:24,470 --> 00:02:26,150
that the user has ready filled it in.
31

32
00:02:26,180 --> 00:02:34,340
So it does, in fact, have a value. In order to represent this uncertainty in Swift, we use something called
32

33
00:02:34,430 --> 00:02:35,500
optionals.
33

34
00:02:35,510 --> 00:02:41,620
So you've seen that when we create a variable, we can specify a data type at the point of creation.
34

35
00:02:41,780 --> 00:02:48,350
So we could add a colon and then add the type of data that this variable or this container or cardboard
35

36
00:02:48,350 --> 00:02:50,410
box is going to store.
36

37
00:02:50,540 --> 00:02:57,170
But then we can add a question mark at the end of our data type to turn it into a completely different
37

38
00:02:57,170 --> 00:03:01,650
data type and it becomes a optional data type.
38

39
00:03:01,670 --> 00:03:08,780
So now this variable hardness can store a string or it can simply be empty.
39

40
00:03:08,780 --> 00:03:13,810
It could have no data or store nil. In a blank playground,
40

41
00:03:13,810 --> 00:03:21,190
I'm going to create a new variable and I'll call it player1Username and I'm gonna set it to be a
41

42
00:03:21,190 --> 00:03:23,140
string data type.
42

43
00:03:23,140 --> 00:03:30,850
And at the very beginning of the game before any player has even gotten the chance to assign themselves
43

44
00:03:30,880 --> 00:03:31,780
a username,
44

45
00:03:32,070 --> 00:03:35,510
well, this variable is not going to contain any data,
45

46
00:03:35,530 --> 00:03:39,820
right? It's going to contain no data or nil.
46

47
00:03:39,820 --> 00:03:47,140
And as soon as you try to run this, because our variable is mostly meant to hold data of string data
47

48
00:03:47,140 --> 00:03:49,430
types, it gives us an error.
48

49
00:03:49,660 --> 00:03:56,200
So we can't just simply take a normal variable container and try to give it no data.
49

50
00:03:56,980 --> 00:03:59,140
What can we do instead?
50

51
00:03:59,140 --> 00:04:07,750
Well, we could instead create a variable called player1Username. and instead of assigning it to a string
51

52
00:04:07,750 --> 00:04:12,580
data type, we give it a string with a question mark at the end.
52

53
00:04:12,580 --> 00:04:15,390
So now it's a optional.
53

54
00:04:15,580 --> 00:04:25,720
And now I can quite easily say that actually this player1Username, it has no data stored
54

55
00:04:25,720 --> 00:04:32,320
in it. But at a later date, I'm going to ask the player, "Well, what is your username?"
55

56
00:04:32,320 --> 00:04:43,550
And they'll give me a username which might-- Let's say, "jackbauerisawesome," so now I have a value inside
56

57
00:04:43,610 --> 00:04:46,410
my optional player1Username.
57

58
00:04:46,550 --> 00:04:54,590
So if I was to print my player1Username at this point, you will see a optional string being printed,
58

59
00:04:54,830 --> 00:04:58,670
So the word "Optional," and then a string.
59

60
00:04:58,670 --> 00:05:05,360
So how can we turn it from an optional, which it is at the moment, which you can see right here, but you
60

61
00:05:05,360 --> 00:05:09,020
can also check by holding down the optional Alt key,
61

62
00:05:09,140 --> 00:05:13,130
you can see that it's data type is clearly an optional string.
62

63
00:05:13,160 --> 00:05:20,150
Well, we could simply just force unwrap it. So we unwrap our box and accept whatever the consequences
63

64
00:05:20,150 --> 00:05:24,800
may be and we try to use the unwrapped version.
64

65
00:05:24,800 --> 00:05:33,580
Now, if I run my code, again, you can see that my optional has become a normal string again.
65

66
00:05:33,890 --> 00:05:44,210
And in fact, if I simply go ahead and create a new variable called unwrappedP1Username and I set
66

67
00:05:44,210 --> 00:05:51,950
it equal to player1Username unwrapped, then you can see that when I check the data type of this
67

68
00:05:51,980 --> 00:05:56,090
unwrappedP1Username, it's now back to a normal string.
68

69
00:05:56,120 --> 00:06:04,880
So it's no longer an optional anymore because I have overridden the safety check. So the safety check
69

70
00:06:04,940 --> 00:06:13,010
is there to prevent us from crashing and burning when we try to do something with a nil value, so a null
70

71
00:06:13,010 --> 00:06:21,330
value. Let's say, if at some later point, I changed my player1Username to, again, equal nil.
71

72
00:06:21,350 --> 00:06:28,160
So let's say that the player has reset their username and, in fact, I'm going to common out this line
72

73
00:06:28,160 --> 00:06:31,190
just to make it a bit clear what's going on here.
73

74
00:06:31,190 --> 00:06:35,920
So we started out by creating a container that can hold nil values,
74

75
00:06:35,930 --> 00:06:41,990
so an optional string data type. And it started out being nil, but then we gave it a value, but then we
75

76
00:06:41,990 --> 00:06:47,860
remove the value and player1Username no longer contains any data on line 10.
76

77
00:06:47,870 --> 00:06:56,960
So now if we try to print it and we unwrap it forcibly, saying that "I am so sure that this will definitely
77

78
00:06:56,960 --> 00:06:59,400
always have data. Computer,
78

79
00:06:59,420 --> 00:07:07,470
listen to your master, which is me the programmer. Just do as I say." And we run it and then all it's going
79

80
00:07:07,470 --> 00:07:14,150
to do is crash. Because if we have a nil value that we're trying to do something with, say, we're trying
80

81
00:07:14,150 --> 00:07:17,830
to add two to nothing. It doesn't make any sense
81

82
00:07:17,840 --> 00:07:28,340
if we try to print nothing, if we try to do anything with a nothing data. It's like taking thin air
82

83
00:07:28,340 --> 00:07:29,910
and trying to do something with it,
83

84
00:07:29,960 --> 00:07:34,970
so that's when our app would crash. In order to prevent this from happening,
84

85
00:07:35,060 --> 00:07:37,400
we can enact some safety checks.
85

86
00:07:37,640 --> 00:07:40,640
The first safety check is, actually, your brain.
86

87
00:07:40,640 --> 00:07:48,350
The reason why a lot of things are optionals are that you are reminded that some of these values can
87

88
00:07:48,350 --> 00:07:50,820
have nil as its value.
88

89
00:07:50,840 --> 00:07:57,040
You want to be able to check through the code and make sure that it won't ever become nil.
89

90
00:07:57,050 --> 00:08:04,550
Now another way of doing this is we can actually just explicitly check to see if player1User name
90

91
00:08:04,580 --> 00:08:07,240
does not equal nil.
91

92
00:08:07,310 --> 00:08:10,240
So that's what that exclamation mark equals mean,
92

93
00:08:10,280 --> 00:08:12,920
means does not equal.
93

94
00:08:12,920 --> 00:08:14,330
And in that case,
94

95
00:08:14,360 --> 00:08:21,440
well, then we could use it and we can unwrap it forcibly. Because now, even though player1Username is
95

96
00:08:21,440 --> 00:08:26,900
equal to nil, our app is no longer going to crash because it's going to bypass the line that would cause
96

97
00:08:26,900 --> 00:08:30,190
an issue because this is not true.
97

98
00:08:30,200 --> 00:08:36,710
Player1 is, in fact, equal to nil. Then we're going to skip the line and we're not going to crash our
98

99
00:08:36,710 --> 00:08:41,320
app by using a piece of data that's nil.
99

100
00:08:41,390 --> 00:08:49,910
Now, there's a really fun comic that somebody once made on "If programming languages were weapons," and
100

101
00:08:50,000 --> 00:08:59,280
one of the biggest problems with a lot of older languages like Java is this idea of a NullPointerException.
101

102
00:08:59,390 --> 00:09:03,650
So this is essentially the same as what we've been talking about.
102

103
00:09:03,670 --> 00:09:11,090
So it says that Java is a belt-fed 240G automatic weapon where sometimes the belt has rounds, sometimes
103

104
00:09:11,090 --> 00:09:11,650
it doesn't.
104

105
00:09:11,690 --> 00:09:18,890
So sometimes it has data, sometimes it's equal to nil. And when it doesn't and you try to fire it, then
105

106
00:09:18,890 --> 00:09:22,860
you get an NullPointerException or you get an error like we did,
106

107
00:09:23,030 --> 00:09:24,500
and the gun explodes and you die.
107

108
00:09:24,620 --> 00:09:31,490
So this is one of the biggest problems with some of these older languages. And the way that Swift was
108

109
00:09:31,490 --> 00:09:37,550
designed is to be a safer language. So the gun doesn't explode in your face and you actually have
109

110
00:09:37,550 --> 00:09:39,080
a fun time using it.
110

111
00:09:39,230 --> 00:09:45,340
But in order for it to work, we have to understand when we're using an optional and to make sure that
111

112
00:09:45,430 --> 00:09:51,550
if we are unwrapping it with an exclamation mark, that we're certain, that it's never going to be equal
112

113
00:09:51,550 --> 00:09:58,080
to nil. If we're not certain, then we should probably check for it and to prevent our app from crashing,
113

114
00:09:58,540 --> 00:10:05,220
so that lines, where we're unwrapping, are optional, are protected by an "if" statement.
114

115
00:10:05,590 --> 00:10:12,480
Now, in later lessons, we're going to dive deeper into some other fancy things that you can do with optionals,
115

116
00:10:13,000 --> 00:10:15,570
such as optional chaining and optional binding.
116

117
00:10:15,640 --> 00:10:23,050
But for now, I just wanted to introduce you to the idea of a nil value that a variable can actually contain
117

118
00:10:23,380 --> 00:10:25,090
no data at all.
118

119
00:10:25,090 --> 00:10:33,940
And the idea that if you tried to do something with nil, then your program will likely crash and optionals
119

120
00:10:34,000 --> 00:10:40,720
are there to safeguard us from these situations, first, by making us think about whether if it could be
120

121
00:10:40,720 --> 00:10:41,600
nil
121

122
00:10:41,650 --> 00:10:45,880
and, second, by getting us to protect against those scenarios.
122

123
00:10:45,940 --> 00:10:51,790
So now that you've learned a bit more about optionals, it's time to complete the assignment that is on
123

124
00:10:51,850 --> 00:10:58,780
Beginning Optionals. And on the next lesson, we're going to head back into building our app.
124

125
00:10:58,780 --> 00:10:59,260
our app.
