0
1
00:00:00,240 --> 00:00:00,750
Hey, guys.
1

2
00:00:00,780 --> 00:00:03,300
Welcome to another Swift Deep Dive.
2

3
00:00:03,510 --> 00:00:09,400
And in this Deep Dive, we're going to learn more about using Optionals.
3

4
00:00:09,450 --> 00:00:17,310
Now previously, you've already been introduced to our ill-fortune cat, Fluffy. And because of our lack of understanding
4

5
00:00:17,310 --> 00:00:20,640
of optionals, we put her life in severe danger.
5

6
00:00:20,640 --> 00:00:25,680
So how can we make sure that we're not getting calls from the animal rights people and make sure that
6

7
00:00:25,680 --> 00:00:27,120
we treat our cat properly?
7

8
00:00:27,660 --> 00:00:30,480
Well, let's see how we can keep her out of harm's way.
8

9
00:00:31,050 --> 00:00:36,300
So what's going to happen in this Deep Dive is I'm going to walk you through five different ways of
9

10
00:00:36,300 --> 00:00:44,280
working with optionals in Swift including force unwrapping, checking for nil values, optional binding, the
10

11
00:00:44,280 --> 00:00:47,600
nil coalescing operator, and optional chaining.
11

12
00:00:47,850 --> 00:00:51,770
So that's a lot of new words, but let's get started.
12

13
00:00:52,080 --> 00:00:57,990
So I'm going to go ahead and create a new macOS command line tool just as we did before,
13

14
00:00:58,440 --> 00:01:01,830
and I'm going to call this OptionalsDemo.
14

15
00:01:01,830 --> 00:01:07,860
And when I go to my main.swift, I'm going to delete everything that's currently inside and I'm just
15

16
00:01:07,860 --> 00:01:10,600
going to use it as we do with our playgrounds.
16

17
00:01:10,620 --> 00:01:18,120
So first things first, I'm going to create a optional, so I call it myOptional and I'm going to give
17

18
00:01:18,120 --> 00:01:22,030
it a dtring data type. But, of course, to turn it into an optional,
18

19
00:01:22,050 --> 00:01:25,440
we just have to add the question mark at the end.
19

20
00:01:25,440 --> 00:01:32,580
Now, notice how the dtring data type is actually completely separate from the optional string data type.
20

21
00:01:33,000 --> 00:01:43,320
So if I was to give myOptional a value, say, "Angela," and if I create a constant which requires a string
21

22
00:01:43,320 --> 00:01:47,310
data type and I tried to set it to equal myOptional,
22

23
00:01:47,310 --> 00:01:54,360
this is not going to work because this expects a string and this has actually a completely different
23

24
00:01:54,360 --> 00:01:56,940
data type, an optional string.
24

25
00:01:56,940 --> 00:02:04,080
So how do we work with optionals? How can we turn it into an actual string that we can put into labels
25

26
00:02:04,080 --> 00:02:08,190
or buttons and manipulate in our code?
26

27
00:02:08,190 --> 00:02:14,850
Well, one of the simplest ways of working with optionals as we've seen is to simply just force unwrap
27

28
00:02:14,850 --> 00:02:16,020
the optional.
28

29
00:02:16,020 --> 00:02:22,230
But this, of course, requires us to really think hard and fast about whether if there's a case where we
29

30
00:02:22,230 --> 00:02:28,500
could be unwrapping the optional and it could actually have a nil value stored. Well, in that case, well,
30

31
00:02:28,560 --> 00:02:30,110
Fluffy gets it.
31

32
00:02:30,210 --> 00:02:35,700
In this case as well, if I go ahead and simply just unwrap the optional, then I make all the errors go
32

33
00:02:35,700 --> 00:02:42,900
away and I kind of am just telling Xcode that "You know what, I know better than you, and I know that
33

34
00:02:42,930 --> 00:02:50,540
this is never going to be nil." But what if myOptional was actually, in fact, storing no value at all?
34

35
00:02:50,550 --> 00:02:53,440
What if it was equal to nil?
35

36
00:02:53,460 --> 00:02:55,040
So in this case, yes,
36

37
00:02:55,140 --> 00:02:59,580
Xcode is not reporting an error, meaning we have no error at the moment,
37

38
00:02:59,580 --> 00:03:04,860
and our project build successfully. But when I run my code, it crashes.
38

39
00:03:04,860 --> 00:03:13,530
So in other words, I experience a crash at what we call runtime. And it crashes on the line where I'm
39

40
00:03:13,530 --> 00:03:19,900
force unwrapping myOptional because it was unexpectedly found to be nil.
40

41
00:03:19,920 --> 00:03:22,230
myOptional was equal to nil.
41

42
00:03:22,260 --> 00:03:26,970
So this is probably the least safe way of working with optional.
42

43
00:03:26,970 --> 00:03:33,210
It requires you to be really concentrated and search through your code to make sure that it can never
43

44
00:03:33,210 --> 00:03:34,850
be nil.
44

45
00:03:34,890 --> 00:03:40,560
So I know in this example, it seems super obvious because we're setting myOptional to nil,
45

46
00:03:40,560 --> 00:03:41,850
two lines earlier.
46

47
00:03:41,850 --> 00:03:47,550
But what if you were working on a more complex project with many files and many lines of code that you
47

48
00:03:47,550 --> 00:03:49,380
can't always keep track of?
48

49
00:03:49,380 --> 00:03:51,940
Well, in that case, it'll be a lot less obvious.
49

50
00:03:51,990 --> 00:03:54,880
So what else can we do?
50

51
00:03:54,900 --> 00:04:02,910
Well, a slightly safer way of working with optionals is to check to see if it's equal to nil. And if
51

52
00:04:02,910 --> 00:04:12,930
it's not, then we force unwrap it and use it in our code. If we had wrapped this line which is crashing
52

53
00:04:12,930 --> 00:04:20,860
our app at the moment, inside an "if" statement where we check if myOptional is not equal to nil,
53

54
00:04:21,250 --> 00:04:23,460
well, in that case, then we can use it.
54

55
00:04:23,910 --> 00:04:30,080
So now if I run my code again, then this line is just going to be skipped.
55

56
00:04:30,090 --> 00:04:31,290
How can we tell it skipped?
56

57
00:04:31,320 --> 00:04:41,030
Well, we can write an "else" statement or we say, "myOptional was found to be nil."
57

58
00:04:41,070 --> 00:04:46,680
So now let's run it again, and you can see we get "myOptional was found to be nil."
58

59
00:04:46,680 --> 00:04:51,330
So this "if" statement was skipped saving us from crashing our app.
59

60
00:04:51,690 --> 00:04:53,540
But here's a problem.
60

61
00:04:53,640 --> 00:04:56,160
This is, firstly, quite wordy.
61

62
00:04:56,250 --> 00:05:04,800
Even though I've already checked to make sure that myOptional is safe to work, I still have to use this
62

63
00:05:04,890 --> 00:05:10,070
exclamation mark to force unwrap the optional every single time.
63

64
00:05:10,110 --> 00:05:16,620
So if I wanted to create another constant, let's say text2: which was a string, and I wanted to be able
64

65
00:05:16,620 --> 00:05:24,300
to work with myOptional, well, again, I can't simply just use it without adding that exclamation mark
65

66
00:05:24,450 --> 00:05:31,740
where I force unwrap it. So this behavior where we are checking to see if the optional contains a nil
66

67
00:05:31,740 --> 00:05:39,820
value, and if it's not nil, then we work with it. It's so common while we're working with Swift optionals,
67

68
00:05:39,820 --> 00:05:44,890
that there is functionality that's built into optionals to handle this.
68

69
00:05:44,890 --> 00:05:47,190
And it's called optional binding.
69

70
00:05:47,190 --> 00:05:56,610
So in this case, what we do is we can write an "if let" to bind the value of the optional if it's not
70

71
00:05:56,610 --> 00:06:05,250
nil to a new constant, and within the curly braces of this "if" statement, we can now work with this safe
71

72
00:06:05,250 --> 00:06:09,540
version of the optional which has been unwrapped.
72

73
00:06:09,540 --> 00:06:18,240
So in this cas,e instead of writing "if myOptional is not equal to nil," I can write "if let safeOptional =  
73

74
00:06:18,930 --> 00:06:21,490
myOptional."
74

75
00:06:21,480 --> 00:06:27,060
Well, in that case, safeOptional is going to equal the value of myOptional.
75

76
00:06:27,300 --> 00:06:30,780
But notice how safeOptional has a data type of string,
76

77
00:06:30,870 --> 00:06:33,880
while myOptional is an optional string.
77

78
00:06:34,080 --> 00:06:40,410
So now if I wanted to work with the value of myOptional, namely the word "Angela,"
78

79
00:06:40,410 --> 00:06:47,460
well, I can now simply use the safeOptional, and you can see that if I decide to print my safe Optional
79

80
00:06:48,540 --> 00:06:56,370
and run my code, you can see that I get the value that's stored inside myOptional printed from the
80

81
00:06:56,370 --> 00:07:04,230
safeOptional. So it's just a way of performing that action of opening up the box seeing if there's anything
81

82
00:07:04,230 --> 00:07:05,160
inside.
82

83
00:07:05,160 --> 00:07:10,600
If it's nil, then simply go ahead and skip and go to the "else" statement.
83

84
00:07:10,710 --> 00:07:18,390
But if it's not nil, then we're going to put the value inside myOptional inside this new temporary constant
84

85
00:07:18,630 --> 00:07:26,620
which we can use inside the curly braces. But this simply just skips the optional
85

86
00:07:26,620 --> 00:07:28,960
if it's equal to nil.
86

87
00:07:28,960 --> 00:07:32,010
What if we wanted to provide it a default value
87

88
00:07:32,050 --> 00:07:36,060
in the case where myOptional is equal to nil,
88

89
00:07:36,100 --> 00:07:38,630
how can we do that?
89

90
00:07:38,740 --> 00:07:44,940
Well, there's another functionality of optionals that comes in really handy right about now.
90

91
00:07:44,940 --> 00:07:53,120
And it's called the Nil Coalescing Operator. And it's simply just two question marks next to each other.
91

92
00:07:53,150 --> 00:07:57,510
That's what it's called. And why is it the nil coalescing operator?
92

93
00:07:57,860 --> 00:08:03,340
Well, because what it does is it checks to see if the optional is nil.
93

94
00:08:03,680 --> 00:08:10,010
If it's not nil, then we're going to use that value. But if it is nil, then we're going to use the provided
94

95
00:08:10,130 --> 00:08:19,090
default value. So in our case, currently, my optional is nil, and I'm going to delete all of this "if" anc
95

96
00:08:19,090 --> 00:08:27,040
and "else" statement right now. And I'm going to try and, again, do the same thing, create a text constant that holds
96

97
00:08:27,040 --> 00:08:33,910
string data type, so real strings, not optional strings, and I want to work with my optional.
97

98
00:08:33,910 --> 00:08:43,330
Now, here I can say myOptional, well, if it has a value, then set that as the value of the text. But if
98

99
00:08:43,330 --> 00:08:50,050
it doesn't have a value, namely if it's nil, then we're going to use the double question mark, the Nil
99

100
00:08:50,050 --> 00:08:55,120
Coalescing Operator, and we're going to provide a default value.
100

101
00:08:55,240 --> 00:08:59,000
So "I am the default value."
101

102
00:08:59,380 --> 00:09:08,050
And now if we go ahead and print our text, then you can see that because myOptional was equal to nil,
102

103
00:09:08,590 --> 00:09:10,890
it was not set as the value of text,
103

104
00:09:10,900 --> 00:09:17,890
instead it's the default value after the nil coalescing operator that was set as the value of text,
104

105
00:09:17,950 --> 00:09:21,270
and that's what's getting printed right now.
105

106
00:09:21,340 --> 00:09:28,720
So those four things that we saw, force unwrapping, checking for nil values, optional binding, as well as
106

107
00:09:28,720 --> 00:09:36,790
the nil coalescing operator, cover all of the cases where our optional is just holding a simple value.
107

108
00:09:36,850 --> 00:09:43,750
Now, there are certain cases where instead of having a optional value, we actually have an optional struct
108

109
00:09:43,960 --> 00:09:45,600
or an optional class.
109

110
00:09:46,000 --> 00:09:49,540
Well, what do we do in that case?
110

111
00:09:49,540 --> 00:09:55,040
Let's say that our myOptional is no longer just a string.
111

112
00:09:55,180 --> 00:10:02,890
Instead, I'm going to create a struct which is called myOptional and it's going to have some properties,
112

113
00:10:04,480 --> 00:10:07,640
so property equals 123
113

114
00:10:07,690 --> 00:10:09,650
and some methods.
114

115
00:10:09,670 --> 00:10:14,790
So we have a method which is just going to print,
115

116
00:10:15,880 --> 00:10:22,130
"I am the struct's method."
116

117
00:10:22,140 --> 00:10:26,600
This is all very simple struct with a property and a method.
117

118
00:10:26,610 --> 00:10:36,630
Now, if I create a optional version, so myOptional and it's going to have myOptional as a data type,
118

119
00:10:37,080 --> 00:10:41,700
but it's an optional, so I haven't yet initialized it.
119

120
00:10:42,330 --> 00:10:49,140
So if I wanted to actually turn it into a real struct, then I would have to say myOptional equals
120

121
00:10:49,140 --> 00:10:49,830
MyOptional
121

122
00:10:49,830 --> 00:10:55,340
and, of course, that set of parentheses will turn it into a real value.
122

123
00:10:55,620 --> 00:11:00,950
So, that was the equivalent of giving the previous optional a value, right?
123

124
00:11:00,990 --> 00:11:02,160
It wanted a string,
124

125
00:11:02,190 --> 00:11:07,170
well, in  this case, it actually wants the structure to be initialized.
125

126
00:11:07,440 --> 00:11:17,580
In this case, if I wanted to tap into the property of this optional or the method of this optional, then
126

127
00:11:17,670 --> 00:11:19,590
how would I go about doing that?
127

128
00:11:19,620 --> 00:11:28,140
So, let's say, I wanted to print myOptional.property. What would actually happen in this case?
128

129
00:11:29,040 --> 00:11:32,980
Well, I can't because this is an optional.
129

130
00:11:33,030 --> 00:11:39,390
So even though the property is not an optional, but because the struct is an optional, we can't actually
130

131
00:11:39,390 --> 00:11:48,760
proceed unless we either unwrap our optional. But if it was nil, then it's a little bit dangerous, right?
131

132
00:11:48,870 --> 00:11:56,520
Because if I turn that into a nil again and run my app, you can see that it's going to crash on this
132

133
00:11:56,520 --> 00:11:57,570
line.
133

134
00:11:57,690 --> 00:12:04,110
So even though the property itself is actually not an optional, it's just an integer, and we can see its
134

135
00:12:04,110 --> 00:12:05,480
value right here,
135

136
00:12:05,580 --> 00:12:11,670
we can't get to it if we haven't yet initialized this structure.
136

137
00:12:11,850 --> 00:12:16,800
So if it's equal to nil, then we can't proceed further.
137

138
00:12:16,830 --> 00:12:24,810
Now, how can we make this code safer? Well, then we would have to use something called Optional Chaining.
138

139
00:12:24,810 --> 00:12:31,620
So in this case, because our optional has some properties or methods that are access using the dot notation,
139

140
00:12:32,220 --> 00:12:38,110
in order to get to it, we add a question mark after the optional.
140

141
00:12:38,460 --> 00:12:46,620
And what this says is if this optional is not nil, then continue along this chain and go ahead and access
141

142
00:12:46,620 --> 00:12:50,110
that property. And we can do the same with methods as well.
142

143
00:12:50,130 --> 00:12:57,180
So if the optional had an associated method, then only when it's not nil do we actually execute that
143

144
00:12:57,180 --> 00:12:59,070
method.
144

145
00:12:59,260 --> 00:13:05,530
So in this case, if we replace this exclamation mark with a question mark, then when we run our app, it
145

146
00:13:05,530 --> 00:13:13,060
won't crash anymore, but this won't be equal to anything either because my optional is currently nil.
146

147
00:13:14,800 --> 00:13:24,700
So we can use this chaining method to access the properties and methods of optional, and this means that
147

148
00:13:24,820 --> 00:13:32,590
if our optional indeed was, in fact, initialized, so it now does have the property and methods set. Then
148

149
00:13:32,620 --> 00:13:41,230
when we run it, it will actually execute that method and it will print "I am the struct's method."
149

150
00:13:41,230 --> 00:13:47,200
So those are some of the five ways that you can use to work with optionals and we're going to be applying
150

151
00:13:47,200 --> 00:13:49,910
that in our app in the next lesson.
151

152
00:13:49,990 --> 00:13:52,510
So continue to the next lesson and I'll see you there.
