Optionals In Swift

A type that represents either a wrapped value or nil, the absence of a value.

Arman
3 min readSep 30, 2021

Swift Official Documentation:

Swift is a type-safe language. A type-safe language encourages you to be clear about the types of values your code can work with.

In Swift, all the (non-optional) variables and constants need to have a value before they can be used. ِBut sometimes, we are not sure what the value will be, for example, if we are fetching data from a server, we don’t know whether we are going to have a response or not. In this case, we need an ability to represent a different state, the absence of a value:

Optional is a type that represents either a wrapped value or nil, the absence of a value.

We can make a variable optional with a question mark ?:

var optionalNumber: Int?

It means we allow the variable to be nil, and therefore our program won't crash if the value is nil. To get the optional’s value, it needs to be unwrapped. So let’s dive into different common ways of unwrapping optionals.

If Let

This is the most common and basic way of unwrapping optionals:

optionalName = "Arman"if let name = optionalName {
print("Unwrapped value; \(name)")
} else {
print("The absence of a value; nil")
}

The name will only be printed if it’s a String rather than nil.

In Swift 5.7 there is a shorthand for if let binding if we use the same name for the constant as we used for the optional:

if let foo {
...
}

Guard Let

This is useful if we want to exit the current function, loop, or condition quickly if the check fails (or is nil) before continuing. Any value we unwrap using guard let will stay inside of the current block after the check:

func printName(name: String?) {
guard let name = name else {
print("nil, exiting function")
return
}
print("Hello! I'm \(name)")
}

It’s common to see guard used at the beginning of functions to verify conditions are correct. This makes our code easier to read and helps us avoid nested if checks.

And again since Swift 5.7, it can be simplified like this:

guard let name else {
...
}

Force Unwrapping

Force Unwrapping returns the value if it exists, otherwise, it throws a fatal error. Optionals can be forced unwrapped by writing an exclamation mark ! after the value:

let forcedUnwrappedNumber = optionalNumber!

Force unwrapping should only be used if there is 100% certainty that the optional has a value, otherwise the program will crash.

Optional Chaining

This is a process for querying properties and methods on an optional value and everything after the question mark ? will only run if our optional has a value:

struct Computer {
var cpu: String
var gpu: String
var ram: String
var storage: Float
}
var myComputer: Computer?
let computerCPU = myComputer?.cpu
if let computerCPU = computerCPU {
print("CPU Model: \(computerCPU)")
}

computerCPU will also be optional.

Nil-Coalescing

Another way is using the double question mark ?? (or the nil-coalescing operator), it will unwrap the optional if it contains a value or returns a default value if it is nil:

let nickName: String = "Tupac!"
let fullName: String? = "Arman Abkar"
let informalGreeting = "Hi \(nickName ?? fullName)"

Since we provide a non-optional (or default) value, we’re guaranteed to have data to work with.

Unit Testing Optionals

When it comes to testing, you can indeed force unwrap optionals but if the value is nil, the program will crash and all the tests will fail. So it is much better to use XCTUnwrap function that only throws an exception if the value is nil, otherwise, it returns the unwrapped value:

let unwrappedNumber = try XCTUnwrap(optionalNumber)

--

--

Arman

Code, conquer, and share. I write about software development and coding challenges. Let's learn and grow together!