Swift Optional Chaining

In swift, optional chaining is the process in which we can query or call the methods, properties or subscripts of an optional that might be nil. Generally, in swift optional chaining will return values in two ways.

 

  • If optional contains a value, then calling the property, method or subscript of an optional will return a value.
  • In case if optional is nil, then calling the property, method or subscription of an optional will return nil.

 

In swift, multiple queries can be chained together due to that if any link in the chain fails or return a nil value, the entire chain will fail and return a nil value.

Swift Optional Chaining as an Alternative to Forced Unwrapping

In swift, if we want to work with the value which is inside an optional, we must unwrap it from the optional by placing an exclamation mark (!) after optional value same way we can add optional chaining by placing a question mark (?) after the optional value on which we wish to call a property, method or a subscript if the optional is non-nil.

 

The main difference is optional chaining will fail gracefully and return a nil when optional is nil but forced unwrapping will throw a runtime error in case if optional is nil. If we use optional chaining (?), we will get result values which are wrapped with a keyword called Optional like Optional(“Tutlane”) but if we use forced unwrapping (!), we will get unwrapped result values without Optional like “Tutlane”.

 

Now we will see how to use Optional Chaining and Forced Unwrapping in a swift programming language with examples.

Swift Optional Chaining (?) Example

Following is the example of using Optional Chaining (?) in a swift programming language.

 

class Student {

var teach: Teacher?

}

class Teacher {

var name = "Suresh Dasari"

}

var stu = Student()

if var stuname =  stu.teach?.name {

print("Name: \(stuname)")

} else{

print("Unable to Retrieve Name")

}

If you observe above example we created a two classes Student and Teacher. Teacher class is having String property called “name” and Student class is having an optional teach property of type Teacher? and we are trying to access “name” property of student’s teach, by placing a question mark (?) using optional chaining.

 

When we execute the above program in swift playground we will get a result like as shown below

 

Unable to Retrieve Name

We got this result because the values are not declared in base class due to that it returns a nil value.

Swift Forced Unwrapping (!) Example

Following is the example of using Forced Unwrapping (!) in a swift programming language.

 

class Student {

var teach: Teacher?

}

class Teacher {

var name = "Suresh Dasari"

}

var stu = Student()

var stuname =  stu.teach!.name

If you observe the above example we created two classes Student and Teacher. Teacher class is having String property called “name” and the Student class is having an optional teach property of type Teacher? and we are trying to access the “name” property of student’s teach, by placing an exclamation mark (!) using forced wrapping.

 

When we execute the above program in swift playground we will get runtime error like as shown below

 

fatal error: unexpectedly found nil while unwrapping an Optional value

We got this error because the values are not declared in the base class and there is no teach value to unwrap.

Swift Model Classes for Optional Chaining & Accessing Properties

Optional chaining gives us the flexibility that we can also declare optional in complex classes where we call any variable, constant properties or etc. This flexibility gives us a way to drill down into sub-properties of similar types, and check that we access those properties which are declared in subclasses.

 

Here is the example in which we declared a two classes, in which one class is complex class and another one is to access its optional value.

 

class Student {

var sch: School?

}

class School {

var classes =  [ClassRoom]()

var noofclasses: Int {

return classes.count

}

subscript (i: Int) -> ClassRoom {

get  {

return classes[i]

}

set  {

return classes[i] = newValue

}

}

func printnoofclasses() {

print("Number of Classes: \(noofclasses)")

}

var add: Address?

}

class ClassRoom {

var classname: String

init(classname: String) { self.classname = classname }

}

class Address {

var sname: String?

var bnumber: String?

func contactAdd() -> String? {

if sname != nil  {

return sname

} else if bnumber != nil {

return bnumber

} else {

return nil

}

}

}

let result = Student()

if let classcount =  result.sch?.noofclasses {

print("School has a \(classcount) Classes")

}

else {

print("Unable to Retrieve No. of Classes")

}

When we run above program in swift playground we will get a result like as shown below

 

Unable to Retrieve No. of Classes

The value of result.sch is nil so the optional chaining call fails and return the above result.

Swift Calling Methods through Optional Chaining

In swift, we can use optional chaining to call a method on an optional value to check whether the method call is successful or not. If method is successfully executed it will show the result, but if method is not succeeding then its show Optional value means nil value.

 

Following is the example of calling methods through an optional chaining in swift programming language.

 

class Student {

var sch: School?

}

class School {

var classes =  [ClassRoom]()

var noofclasses: Int {

return classes.count

}

subscript (i: Int) -> ClassRoom {

get  {

return classes[i]

}

set  {

return classes[i] = newValue

}

}

func printnoofclasses() {

print("Number of Classes: \(noofclasses)")

}

var add: Address?

}

class ClassRoom {

var classname: String

init(classname: String) { self.classname = classname }

}

class Address {

var sname: String?

var bnumber: String?

func contactAdd() -> String? {

if sname != nil  {

return sname

} else if bnumber != nil {

return bnumber

} else {

return nil

}

}

}

let result = Student()

if result.sch?.printnoofclasses() != nil {

print("Possible to print number of classes")

}

else {

print("Not possible to print number of classes")

}

When we run above program in swift playground we will get a result like as shown below

 

Not possible to print number of classes

This is how we can call methods in optional chaining in a swift programming language.

Swift Accessing Subscript through Optional Chaining

In swift, optional chaining allows us to access and set a values from subscripts through its index and it allow us to call the values which are not present in the list. For those values, it prints an Optional value which is nil. If the value is matching in a list, then it succeeds and print the specific value.

 

Following is the example of a set and accessing subscript values through optional chaining in swift programming language.

 

class Student {

var sch: School?

}

class School {

var classes =  [ClassRoom]()

var noofclasses: Int {

return classes.count

}

subscript (i: Int) -> ClassRoom {

get  {

return classes[i]

}

set  {

return classes[i] = newValue

}

}

func printnoofclasses() {

print("Number of Classes: \(noofclasses)")

}

var add: Address?

}

class ClassRoom {

var classname: String

init(classname: String) { self.classname = classname }

}

class Address {

var sname: String?

var bnumber: String?

func contactAdd() -> String? {

if sname != nil  {

return sname

} else if bnumber != nil {

return bnumber

} else {

return nil

}

}

}

let ins = School()

ins.classes.append(ClassRoom(classname: "Tutlane"))

let result = Student()

result.sch = ins

if let clsname = result.sch?[0].classname {

print("Class Name: \(clsname)")

}

else {

print("Class Name not Specified")

}

If you observe above example we are setting and retrieving subscript values using optional chaining.

 

When we run the above program in swift playground we will get a result like as shown below

 

Class Name: Tutlane

This is how we can set and retrieve subscript values using index in optional chaining based on our requirements.

Swift Accessing Subscripts of Optional Type

If subscript return a value an optional, we can modify the values of array or dictionaries which is declare with an optional type.

 

Following is the example of accessing subscript optionals through optional chaining in a swift programming language.

 

var students = ["Suresh": [90,75,81], "Trishika": [100,99,98]]

students["Suresh"]?[0] -= 12

students["Trishika"]?[2] += 2

print(students)

If you observe above example we have a dictionary object called “students” and it contains a two key-value pairs that map a String key to an array of Int values. In example we used an optional chaining to set the values in "Suresh" and "Trishika" arrays.

 

When we run above program in swift playground we will get a result like as shown below

 

["Suresh": [78, 75, 81], "Trishika": [100, 99, 100]]

This is how we can access subscripts of an optional type using optional chaining based on our requirements in swift programming language.