? ! guard let ??

All about Optionals in Swift

This is my first post on iOS and I will be addressing the elephant (optionals) in the room (Swift).

A lot of us struggle while using optionals and lean on the Xcode correction suggestions. So in this post I will be helping you become your own boss so that you can stop taking Xcode’s advices all the time \o/

Optionals were introduced in Swift so that we could avoid Null Pointer Exceptions (NPE) or as Xcode says “fatal error: unexpectedly found nil while unwrapping an Optional value”.

You can avoid NPEs only if you code in the right way. How so? Let us dive in.

Here’s what we will be learning:

Topic One: Optionals declared with a Question Mark - ?

Disclaimer: This is going to be a lengthy topic, so hang tight and prepare for a flight.

Let’s start here by declaring a variable called name.

var name:String?  

//Which is similar to

var name:String? = nil

Now that we’ve created the variable name with nothing (or nil), when we try to access (which is a crime – since it has no value), it should cause a disaster.

print(name!) //fatal error: unexpectedly found nil while unwrapping an Optional value

Let us appreciate the politeness of Xcode and try to avoid the Null pointer Exceptions from now on.

Enter guard keyword.

Guard is the equivalent of checking if a variable is nil or not.

Guard in action:

var name:String?  

guard name != nil else { 
    print("Nameless :/") //This is printed since name is nil
    return
 }

print(name!) //This line is not executed, since name is nil and return was called.

Explanation: With the help of guard we checked if name has a value, since it does not have a value our message “Nameless :/” was printed.

Well this solved our problem of avoiding NPE. But I don’t like to forcefully unwrap a variable (like name!). So let us write the above code in a better way.

Enter guard let

var name:String?  

guard let safeName = name else {  //Observe let 
    print("Nameless :|") //This is printed since name is nil
    return
 }

print(safeName) //No need of ! to forcelly unwrap 

Explanation: By using guard let and creating a new constant, we didn’t have to check for nil and in return we got a safe or a non-optional constant called safeName which doesn’t need forceful unwrapping. While everything else remains the same, not having to use ! is a relief now and I don’t have to remember to unwrap the optionals whenever I need to read its value.

Now you’re thinking, “I will just use the if-condition instead of guard”. Let’s consider a hypothetical scenario where you may have to use a lot of nil checks as follows:

var name:String?  
var phoneNumber:String?
var email:String?
var address:String?
var dob:String?

var user = [String:Any]()
if name != nil {
    if dob != nil {
        if address != nil {
            if phoneNumber != nil {
                if email != nil {
                     user = [
                        "name" : name!,
                         "address": address!,
                         "phoneNumber": phoneNumber!,
                         "email": email!,
                         "dob":dob!
                     ]
                     //..........
                } else {
                    showAlert("email is nil")
                }
            } else {
                showAlert("phoneNumber is nil")
            }
        } else {
            showAlert("address is nil")
        }
    } else {
        showAlert("dob is nil")
    }
} else {
    showAlert("name is nil")
}

Such a lovely code (Sarcasm intended). Let’s make it beautiful with guard and let.

var name:String?  
var phoneNumber:String?
var email:String?
var address:String?
var dob:String?

guard let safeName = name else {
    showAlert("name is nil")
    return
}

guard let safePhoneNumber = phoneNumber else {
    showAlert("phoneNumber is nil")
    return
}

guard let safeEmail = email else {
    showAlert("email is nil")
    return
}

guard let safeAddress = address else {
    showAlert("address is nil")
    return
}

guard let safeDob = dob else {
    showAlert("dob is nil")
    return
}

 user = [
       "name" : safeName,        
       "address": safeAddress,
       "phoneNumber": safePhoneNumber,
       "email": safeEmail,
       "dob": safeDob
     ]

Doesn’t this look beautiful? More readable? Such code? Much wow!

Can I ever avoid using guard let and force unwrapping altogether?

Well in a few cases, you can.

Enter Coalescing operator (??)

var name:String?  

print("Hi " + name ?? "buddy") //Hi buddy

Explanation: We didn’t have to unwrap name like name! thanks to the coalescing operator. If name is nil, then the string “buddy” is used.

The print statement in the above example with the coalescing operator is similar to the following line:

 print(name != nil ? "Hi " + name : "Hi buddy")

—————– X —————–

Topic two: Optionals declared with an Exclamation Mark - !

Declaring an optional with ? had a lot cavieats, let us now move forward with another way of declaring an optional, which is, by using the Exclamation mark.

Example:

var name:String!

print(name) //fatal error: unexpectedly found nil while unwrapping an Optional value

Yet another way, yet another null pointer exception. Fear not, I can explain.

Declaring an optional with an Exclamation mark avoides the usage of the Exclamation mark while reading the value, but it is still vulerable to a null pointer exception if you forgot to assign a value to it.

Then why do we have this confusing way of declaring an optional? We should use this kind of Optional in places where you know for sure that you are going to initialize the Optional with a value before you access it. No where else you should be using this (as far as I know) otherwise you will suffer from Null pointer exceptions )-D

Example usage 1:

var name:String!

init(with name:String) {
    self.name = name //Pretty good usage. Access name without exclamation everywhere.
}

Example usage 2:

var textField:UITextField! //You link this to a UITextField in the Storyboard.
//Yet another good usage.

Every other concept that we walked through in Topic one can be used in the same lines in Topic two. (Except, of course, we do not need ! to unwrap the value.)

—————– X —————–

Topic Three: Optional lets

I hope that you’re familiar with creating constants in Swift (using the let keyword instead of var). Once we assign a value to a constant, then we’re stuck with that value.

What if I told you, that we can have optional constants in Swift.

Example:

let iHoldNothingForever: String? = nil //Will always be nil. A-L-W-A-Y-S.

Ok, now let’s deal with a more realistic example here!

let notSureWhatIHold: String? =  array.first //May or may not be nil.

Now, in this realistic example. The value of our constant notSureWhatIHold depends on the array variable. If the array has a value then, notSureWhatIHold is not nil else it going to be nil. Ez Pz Simple Pimple.

—————– X —————–

So be very aware of the vars in your code-closet. You never know which ones can be fatal ;)

Hit the <3 below if you’ve learned something out of this post and comment below if you have any questions. Share this amongst your peers as well!

deinit { //me }