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