Swift optionals simplified

If you are an iOS developer, you probably might have came across swift language . Most of you might have became en expert in swift by this time.

When I started learning swift I suffered a lot understanding optionals in swift. Even now I am not an expert in swift, but I thought about sharing what I know with you guys. So, lets begin.

Optionals are the fundamental part of swift coding. Keeping it simple , we can say that optionals helps us to separate good code from bad code and hence prevent crashes.

Different programming languages uses different preventive measures to avoid a crash. But most of them are helpless in most of the cases. Swift however is more practical in this case and optionals will help you to make your code crash free. Well that’s not 100 percent true, but however it will help you to make a much better code.

Optionals either hold no value or hold some value. Optionals allow storing nil, a.k.a absence of value.
//just for a basic understanding..
enum Optional {
case none
case some(Wrapped)
}

So, lets get started. Open your xcode and create a new playground. Let’s start swifting.

//: Playground - noun: a place where people can play
import UIKit
var numberOfCrashes : Int?

Just have a look at the above code. The question mark (?) at the end denotes that it is an optional variable. If you see a question mark at the end of a variable declaration, just understand that it may or may not contain a value in it. So, at some part of your program, you don’t know if there is a value or not for a variable, then mark it as optional.

Now, try to print the value of the variable ‘numberOfCrashes’.

print(numberOfCrashes!)

The exclamation point (!) at the end of the variable is used to unwrap the value. At this point, the code will crash. That is because, you just force unwrap an optional variable with no value in it. You just took an optional variable and said “hey! ,give me the value out of it”, and you try to use it. But if you do this, and there is no value in the variable, then your program will crash.

//: Playground — noun: a place where people can play
import UIKit
var numberOfCrashes : Int?
numberOfCrashes = 3
print(numberOfCrashes!)

But if you set a value to the variable before you force unwrap the value, the code will not crash. But this way you are actually abusing the optional variable. You will not be lucky like this every time. But this is bad coding practice.

What do we do now? May be we should do a nil check before we force unwrap an optional.

//: Playground — noun: a place where people can play
import UIKit
var numberOfCrashes : Int?
if numberOfCrashes != nil {
print(numberOfCrashes!)
}

Now your code will not crash as you are force unwrapping it the optional variable only after a nil check.

The swift way of doing the nil check is by using a if let statement(Optional binding.. mentioned later in this article).
//: Playground — noun: a place where people can play
import UIKit
var numberOfCrashes : Int?
if let crashCount = numberOfCrashes {
print(crashCount) // same as print(numberOfCrashes!)
}

The above method will check if the optional variable ‘numberOfCrashes’ contains some value or not. If exists, then it will be copied to a constant called crashCount and then only the code block will get executed.

Anytime you see an optional variable with a question mark, then use the if-let statement to make sure it’s not nil.

Note: If you define an optional variable without providing a default value, the variable is automatically set to nil for you:

var surveyAnswer: String?
// surveyAnswer is automatically set to nil

Unwrapping optionals

It can be done in few ways:

◙ Force unwrapping

◙ Implicit unwrapping

◙ Optional binding

— Forced unwrapping :

If you defined a variable as optional, then to get the value from this variable, you will have to unwrap it. This just means putting an exclamation mark at the end of the variable. This way of unwrapping by directly putting an exclamation mark at the end while accessing is called Forced unwrapping.

Forced unwrapping is error prone and is not recommended.
var myString:String?

myString = "Hello, Swift!"
let x = myString! // forced unwrapping Success!!!
//_______________________________
var myOtherString:String?

let x = myOtherString! // forced unwrapping Error. The value is not set.

— Implicit unwrapping :

An Implicitly Unwrapped Optional is an optional that doesn’t need to be unwrapped because it is done implicitly. These types of optionals are declared with an (!) instead of a (?). The only change is that this time the compiler will not yell at you. You can use it like a normal variable. Such optional variables will unwrap automatically and you do not need to use any further exclamation mark at the end of the variable to get the assigned value.This way of unwrapping is called implicit unwrapping .But keep in mind that the risk of crashing is high as you will have to manually keep track of the variable usage.

let someString: String! 
print(someString) // risk for crash is high.

We don’t have to use ! to print out the value of someString. Just like forced unwrapping, accessing an implicitly unwrapped optional that is nil will cause the entire program to crash with a runtime error.

Well, we can use our Vehicle class to give an example.

import UIKit
class Vehicle {
var model: String!
}
var cars = Vehicle()
print(cars.model) // it may crash the app sometimes. the value is nil.
By using an implicitly unwrapped optional, we are guaranteeing the compiler that we will assign some value to it sometimes in the future.

In most cases, Implicitly Unwrapped Optionals should be avoided because you cannot keep track of all your variables all the time and your entire app will crash when it is accessed while nil. If you are ever not sure about whether a variable can be nil, always default to using a normal Optional. Unwrapping a variable that is never nil certainly doesn’t hurt very much.

Implicit unwrapping is error prone and is not recommended.

Let’s take a simple example −

var myString:String!

myString = "Hello, Swift!"
let x = myString // x is an optional string with value "Hello, Swift!"
//_______________________________
var myOtherString:String!

let x = myOtherString // x will be an optional string. The value is not set (or nil).

Forced vs implicit unwrapping :

let possibleString: String? = "An optional string."
let forcedString: String = possibleString! // requires an exclamation mark
_______________
let assumedString: String! = "An implicitly unwrapped optional string."
let implicitString: String = assumedString // no need for an exclamation mark

—Optional Binding :

Use optional binding to find out whether an optional contains a value, and if so, to make that value available as a temporary constant or variable.

An optional binding for the if statement is as follows −

if let constantName = someOptional {
//statements using 'constantName'
} else {
// the value of someOptional is not set (or nil).
}
This is the recommended way of unwrapping an optional.
let possibleNumber = "123" // a string  nonOptional constant
if let actualNumber = Int(possibleNumber) {
print("\"\(possibleNumber)\" has an integer value of \(actualNumber)")
} else {
print("\"\(possibleNumber)\" could not be converted to an integer")
}
// Prints ""123" has an integer value of 123"

This code can be read as:

“If the optional Int returned by Int(possibleNumber) contains a value, set a new constant called actualNumber to the value contained in the optional.”

You can include as many optional bindings and Boolean conditions in a single if statement as you need to, separated by commas. If any of the values in the optional bindings are nil or any Boolean condition evaluates to false, the whole if statement’s condition is considered to be false. The following if statements are equivalent:

if let firstNumber = Int("4"), let secondNumber = Int("42"), firstNumber < secondNumber && secondNumber < 100 {
print("\(firstNumber) < \(secondNumber) < 100")
}
// Prints "4 < 42 < 100"
if let firstNumber = Int("4") {
if let secondNumber = Int("42") {
if firstNumber < secondNumber && secondNumber < 100 {
print("\(firstNumber) < \(secondNumber) < 100")
}
}
}
// Prints "4 < 42 < 100"
Constants and variables created with optional binding in an if statement are available only within the body of the if statement. In contrast, the constants and variables created with a guard statement are available in the lines of code that follow the guard statement.

Digging deeper :

Let’s understand a little more about optionals. Let’s understand how optionals are used inside classes.

Let’s create a class with an optional variable.

//: Playground — noun: a place where people can play
import UIKit
class Vehicle {
var model: String?
}

Here, the class Vehicle contains an optional variable called model. Now we are going to create a car of type Vehicle.

var car: Vehicle?

This variable car is a optional variable. This means that at some point of time, it may contain a value in it. SO, now if we want to get the model of the car, what do we do? May be we can do a multi level if-let statement like this:

//: Playground — noun: a place where people can play
import UIKit
class Vehicle {
var model: String?
}
var car: Vehicle?
if let c = car {
if let m = c.model {
print(m)
}
}

It will work fine. But there is a better way.

if let c = car, let m = c.model {
print(m)
}

This is a single line if-let statement. First it will check the first statement. If it is valid, then the next statement towards the right will get executed and so on.Now let us see the working code:

//: Playground — noun: a place where people can play
import UIKit
class Vechicle {
var model: String?
}
var car: Vechicle?
car = Vechicle() // created a new vehicle
car?.model = “Lamborgini”
if let c = car, let m = c.model {
// only execute if car is valid and car has a valid model..
print(m)
}
IMP: Whenever we are using an optional with a question mark at the end, anytime you are going to use the dot(.) to access the property or something, you’ve got to put a question mark in front of it and say ‘Hey, it’s an optional and I don’t know if there is a value inside or not.

For a better understanding, lets create an array of vehicle which is optional.

import UIKit
class Vehicle {
var model: String?
}
var cars: [Vehicle]?
cars = [Vehicle]()
cars?.append(Vehicle()) // question mark in front of the dot is because it is an optional variable. 
if let carArray = cars, carArray.count>0 {
//execute only if cars array is valid and its count is greater than zero.
print(carArray.count)
}

Optional chaining :

Consider a class Human with an non- optional variable called age .

import UIKit
class Human {
var age: Int
init(age: Int) {
self.age = age
}
}

Consider another class House with an optional variable of type Human .

class House {
var human:Human?
}

Now we can create an object of House and initialise the age of human with a value.

var houseObj = House()
houseObj.human = Human(age: 10)

Now let’s try to access the age of the human in the house.

let ageOfHumanInHouse = houseObj.human?.age //ageOfHumanInHouse is optional Int

Since the type of human is optional, ?gets added automatically. When you access a property whose type is optional, Swift will add ?. Anything that comes after the ? will be optional.

IMPORTANT: Even though age is not an optional variable, since human is optional, the age has to be optional as human may be nil.
Its pretty simple.Lets assume that you saw a dream and you have a luxury house in your dream. The house in the dream is not real and you know that . So everything inside the house like a 100 inch curved LED tv , a lamborghini car in the garage , a luxury bed in the bedroom etc.. everything will be imaginary. Its just pure common sense.

Since ageOfHumanInHouse is optional Int (Int?) , we can use optional binding to unwrap it.

if let ageOfHumanInHouse = ageOfHumanInHouse {
print(“\(ageOfHumanInHouse)”)
}
Important: Optionals don’t interact with each other. We have to unwrap an optional in order to do that.

What is the nil coalescing operator?

source: Hackingwithswift

Optionals are a powerful source of safety in Swift, but can also be annoying if you find them littered throughout your code. Swift’s nil coalescing operator helps you solve this problem by either unwrapping an optional if it has a value, or providing a default if the optional is empty.

Here’s an example to get you started:

let name: String? = nil
let unwrappedName = name ?? "Anonymous"

Because name is an optional string, we need to unwrap it safely to ensure it has a meaningful value. The nil coalescing operator – ?? – does exactly that, but if it finds the optional has no value then it uses a default instead. In this case, the default is "Anonymous". What this means is that unwrappedName has the data type String rather than String? because it can be guaranteed to have a value.

You don’t need to create a separate variable to use nil coalescing. For example, this works fine too:

let name: String? = nil
print("Hello, \(name ?? "Anonymous")!")

If you enjoyed reading this post, please share and recommend it so others can find it 💚💚💚💚💚💚 !!!!

One clap, two clap, three clap, forty?

By clapping more or less, you can signal to us which stories really stand out.