Table of contents
1.
Introduction
2.
Swift Optional Chaining
3.
Optional Chaining in Place of Forced Unwrapping
3.1.
Code
3.2.
Output
3.3.
Code
3.4.
Output
3.5.
Code
3.6.
Output
4.
Model Classes for Optional Chaining
4.1.
Code
4.2.
Output
4.3.
Code Explanation
4.3.1.
Model class 1
4.3.2.
Model Class 2
4.3.3.
Model Class 3
4.3.4.
Model Class 4
5.
Use of Optional Chaining
5.1.
Access Properties Through Optional Chaining
5.1.1.
Code
5.1.2.
Output
5.2.
Call Methods through Optional Chaining
5.2.1.
Code
5.2.2.
Output
5.3.
Access Subscripts through Optional Chaining
5.3.1.
Code
5.3.2.
Output
6.
Frequently Asked Questions
6.1.
What is Optional Chaining in swift?
6.2.
What is Forced Unwrapping in swift?
6.3.
What are Optionals?
6.4.
Where do we use Optional Chaining?
6.5.
What is the return type of a function that doesn't return anything?
7.
Conclusion
Last Updated: Mar 27, 2024
Medium

Swift Optional Chaining

Career growth poll
Do you think IIT Guwahati certified course can help you in your career?

Introduction

You might have used optionals in swift many times till now. Optionals are a type of container with only two possibilities: either it can contain a value or null. Now, how do we handle the optionals? That is what we are going to discuss in this article.

swift optional chaining

In this article, we will discuss Swift Optional Chaining and what is the need for swift optional chaining. We will also discuss if swift optional chaining is better than forced unwrapping and why. Then we will see how forced unwrapping creates runtime errors which, in the case of swift optional chaining, it is handled gracefully. We will also see different scenarios where we can use swift optional chaining, and we will explain everything with examples for your better understanding.

Swift Optional Chaining

The technique of querying and calling propertiesmethods, and subscripts on an optional is known as optional chaining.

Now, what is an Optional 🤔? As evident by its name, it will give you options. By using an optional, you can use one thing or the other. It's similar to an MCQ question where you have two options, either this or that.

We get the Optional part, but why Chaining 🤔? It is called Chaining because multiple queries can be chained together to form a nested if-else-like structure.

The entire chain fails if any of these properties, methods, or subscripts are nil when accessed. There are only two possibilities for each of them, and that is either there is a value, or it is nil.

Now, you can argue why we would use Swift Optional Chaining if we already have forced unwrapping. We have discussed this below.

Optional Chaining in Place of Forced Unwrapping

We will understand the difference between forced unwrapping and optional chaining using an example.

Let's suppose there is a property of a class that you want it to be optional. For example, there is a laptop class that contains a property named specification which stores the details of that laptop. Let's say you don't have the details of a laptop; then the specification property can be optional, as shown below.

class Laptop {
 /* Adding (?) sign after details
 because this is optional property */
 var specification : details?
}
class details {
var brand = "HP"
var RAM = "16 GB"
}

When we create an instance of the Laptop class, the specification property will be nil. So, let's try to access this by using both methods: forced unwrapping and optional chaining.

Forced unwrapping is done using a (!) sign after the optional property, as shown below.

Code

class Laptop {
 var specification : details?
}
class details {
var brand = "HP"
var RAM = "16 GB"
}
// Creating instance of Laptop
let device = Laptop()
// Forced unwrapping
let memory = device.specification!.RAM

Output

output screenshot

The above code produces a runtime error because the property we are trying to access is nil.

Now, let's do this using Swift Optional Chaining. In optional chaining, if the optional contains a value, the remaining code in the chain is executed, but if it is nil, then the chain is broken, and else part of the code is executed. It is implemented in the code given below.

Code

class Laptop {
 var specification : details?
}
class details {
var brand = "HP"
var RAM = "16 GB"
}
// Creating instance of Laptop
let device = Laptop()
// Optional Chaining
if let memory = device.specification?.RAM {
 print("Laptop has \(memory) RAM memory.")
}
else {
 print("RAM details not available for this laptop")
}

Output

output screenshot

Since the accessed property was nil, it executed the else part of the code and returned this output.

Now, let's assign the 'details' instance to 'device.specification' so that it no longer contains a nil value. If we try to access the specification property, it will go in the if condition. You can refer to the code below to check for yourself.

Code

class Laptop {
 var specification : details?
}
class details {
var brand = "HP"
var RAM = "16 GB"
}
// Creating instance of Laptop
let device = Laptop()
device.specification = details()
// Optional Chaining
if let memory = device.specification?.RAM {
 print("Laptop has \(memory) RAM memory.")
}
else {
 print("RAM details not available for this laptop")
}

Output

output screenshot

Model Classes for Optional Chaining

Swift Optional chaining can be used with properties, methods, and subscripts having multiple levels. This will allow us to go deep into the levels and check whether it's possible to access them.

Let us build a complex class structure which we will then use as an example to understand how optional chaining works with properties, methods, and subscripts. The code for the classes is given below. The explanation for the construction of these classes is given below the code.

Code

// Model class 1
class Libraries {
   var library : Library?
}
// Model class 2
class Library {
   var books: [Book] = []
   var numberOfBooks: Int {
       return books.count
   }
   subscript (i: Int) -> Book {
     get  {
       return books[i]
     }
     set  {
       return books[i] = newValue
     }
   }
   func printNumberOfBooks() {
       print("The number of books is \(numberOfBooks)")
   }
   var location : Location?
}
// Model class 3
class Book {
   let name: String
   init(name: String) { self.name = name }
}
// Model class 4
class Location {
   var Area : String?
   var StreetName : String?
}
// Initializing college class
let library1 = Libraries()
if let bookCount =  library1.library?.numberOfBooks {
 print("Library has \(bookCount) number of books")
}
else {
 print("Book information of this library is not available")
}

Output

output screenshot

We get this output because library1.library is nil. So, it will go in the else condition, and print Book information of this library is not available.

Code Explanation

Model class 1

class Libraries {
   var library : Library?
}

The Libraries class has an optional library property.

Model Class 2

class Library {
   var books: [Book] = []
   var numberOfBooks: Int {
       return books.count
   }
   subscript (i: Int) -> Book {
     get  {
       return books[i]
     }
     set  {
       return books[i] = newValue
     }
   }
   func printNumberOfBooks() {
       print("The number of books is \(numberOfBooks)")
   }
   var location : Location?
}
  • The 'Library' class defines a variable property, namely 'books,' which is initialized with an array of type '[Book].'
  • numberOfBooks property returns the value of the 'count' property showing the count of the books array. It is implemented as a computed property, not a stored property.
  • Subscript provides read-write access to the book at the desired index in the books array.
  • printNumberOfBooks is a method that simply prints the number of books in the 'library.'
  • It defines a 'location' property which is optional with a type of 'Location?'.

Model Class 3

class Book {
   let name: String
   init(name: String) { self.name = name }
}

The Book class is a simple class with one property called name and an initializer to set that property to a suitable book name. It is used in the 'books' array.

Model Class 4

class Location {
   var Area : String?
   var StreetName : String?
}

Location class has two optional properties of type String? to identify the location.

Now, we will use these model classes to understand further concepts.

Use of Optional Chaining

Optional chaining can be used with propertiesmethods, and subscripts in the below-given ways.

  • Accessing properties through Optional Chaining
  • Calling methods through Optional Chaining
  • Accessing subscripts through Optional Chaining

Access Properties Through Optional Chaining

This is similar to what we did in our first demonstration, where we tried to access a nil property. For the above code, if we create an instance of the 'Libraries' class and then try to access the 'numberOfBooks' property using optional chaining, then we will go to the else condition because that property is nil.

You can add the code given below to the previous code and see the new output. The output shows that the else condition is visited and the 'if' condition is not visited due to the reason mentioned above.

Code

let library2 = Libraries()
if let bookCount = library2.library?.numberOfBooks {
   print("This Library has \(bookCount) books.")
} else {
   print("No info on number of books")
}

Output

output screenshot

Suppose we try to assign a new location to the location property of the library of library2. In that case, it won't work because the '=' operator comes after the optional chaining '?' operator. Hence, the assignment is also part of optional chaining, and since its property is nil, it won't see the code after the '?' operator.

The code for this is given below.

let newLocation = Location()
newLocation.Area = "Rajinder Nagar"
library2.library?.location = newLocation

Call Methods through Optional Chaining

Similar to accessing properties, optional chaining can be used to call methods and check whether that method call is successful.

For example, in the above code, if we try to access the printNumberOfBooks() method through optional chaining, it will send us to the else part because the department property of the 'library2' instance of the 'Library' class is still nil.

Note: functions and methods having no return type have an implicit return type of 'Void?'

You can refer to the code given below to relate to this.

Code

if library2.library?.printNumberOfBooks() != nil {
   print("Info on number of books is available")
} else {
   print("Info on number of books is not available")
}

Output

output screenshot

Access Subscripts through Optional Chaining

We can use the optional chaining technique to try to get and set a value from a subscript on an optional value and then check whether that subscript call is successful.

In our example code, add the code given below.

Code

if let NameOfFirstRoom = college2.department?[0].name {
   print("The first room name is \(NameOfFirstRoom).")
} else {
   print("Not able to get room name")
}

Here, we are trying to access the name property of the first room in the 'rooms' array using subscripts with optional chaining. Since college2.department is nil, therefore we will go to the else part. So, the output will be from the else part.

Output

output screenshot

Similarly, if we try to assign a 'Book' to 'library2.library', then also we won't be able to do that because of the same reason.

library2.library?[0] = Book(name: "Coding Ninjas Studio")

This also fails because library2.department is nil.
Check out this problem - Longest String Chain

Frequently Asked Questions

What is Optional Chaining in swift?

The technique of querying and calling propertiesmethods, and subscripts on an optional is known as optional chaining.

What is Forced Unwrapping in swift?

It is the action of extracting the value contained inside an Optional.

What are Optionals?

Optional is a type of container which may or may not contain a value.

Where do we use Optional Chaining?

Optional chaining can be used to access properties, calling methods, and accessing subscripts.

What is the return type of a function that doesn't return anything?

Functions and methods having no return type have an implicit return type of 'Void?'

Conclusion

This article taught us about Swift Optional Chaining and what is the need for optional chaining. We also discussed how optional chaining counters the run time error problem of forced unwrapping and the use cases of optional chaining. We hope this blog has helped you enhance your iOS and swift knowledge. Here is a list of articles that can help you learn more about ios development and swift.

Refers to our guided paths on Coding Ninjas Studio to learn more about DSA, Competitive Programming, JavaScript, System Design, etc. Enroll in our courses and refer to the mock test and problems available. Take a look at the interview experiences and interview bundle for placement preparations.

Happy Learning Ninja! 🥷

Live masterclass