Property Observers in Swift 5
In this article, I will be explaining what are property observers in Swift 5, how to utilize them and give some examples for their most used cases.
Firstly, I want to briefly talk about what are properties. Properties are variables or constants that are stored in a class or a struct instance. They are used to store valuable information that can or cannot be changed at later stages of the application run time for classes or structs.
When we initialize Person struct, we set values of these properties in order to get information from Person instance in functions later.
Property Observer — as the name suggests — creates an observer to a specific property to listen for changes and make the corresponding action when a change happens. There are two property observers called willSet and didSet in Swift 5. They behave similarly with few differences.
When we add willSet property observer to a property, it listens for changes as any observer does and calls the code inside its block when a change for that property is about to happen. It usually used for doing something just before the value of related property is changed. Here is an example to make it clearer.
Let’s say we want to implement a neat iOS application for our friend John that celebrates his birthdays. We create a Person class with two properties of name and age. Name is a constant since his name most probably won’t be changing. Age property will increment by 1 for his every birthday. We will assure that functionality with a function called incrementAge().
We attached a willSet observer to the age property in order to print the value of the age property when its value is changed. Now, times have past and John’s birthday has come. Our app called incrementAge() function and set the value of age property from 33 to 34. Just before changing old value to its new value, willSet property observer will be triggered and execute its code block. Therefore, in the sample code above, the print statement will print out “age is 33”.
willSet property observer intercepted the value change before the value of the property is changed, and executed the code below. So, the value of age property was still 33 at the moment the willSet block is executed. Let’s say we also want to get the new value of the property and do something with both old and the new value. There is a hidden property of willSet that gives us such ability.
The newValue keyword stores the value that the property is about to be changed to. Since willSet will be triggered before change action of value of the property happens, the property of “age” is still the old value and the “newValue” property of willSet has the new value. Therefore, the print statement from the above example prints out: “the old age was 33 and the new age is 34”.
Similar to willSet property observer, didSet also listens to changes for the specific property, but unlike willSet, didSet is triggered after the value of the property is changed. Here is the same example from above with didSet property observer attached to the age property.
This time, we attach a didSet property observer to the age property of Person class. When John’s birthday comes, incerementAge() function would be invoked and increase the value of the age property from 33 to 34. Since the didSet property observer is triggered after the change is happen for the property, the print statement above will print “age is 34”.
Since the didSet property observer is called after the change for value of the property happens, it print the value of age as 34 which is the value of age property after incrementing. There is also a hidden property in didSet in order to get the value before the change happens.
The oldValue property in the didSet block stores the old value (the value of the property before the change happens). Hence, the print statement above prints out “the new age is 34 and the old age was 33” to the console.
There are a lot of use cases that these property observers really helps out. One particular example for this is implementing an observer pattern to this class in order to broadcast the changes to other classes such as other UIViewControllers to notify the change. One other use case of property observers is when they are used to reload the UITableView when the main data source for this table view changes. Here is a real life example from an application.
Brief explanation of the code above; We create two properties, one for all the universities and other is for the universities that are searched by entering some keyword. They have both a didSet property observer in order to observe the changes, and reload the table view to show the searched universities or the whole university array when their value is changed. We attach a SearchController to our UITableViewController to add the search functionality. After that, we create the other related function such as UITableViewDelegate and DataSource functions to make the functionality above work.
With adding the tableView.reloadData() in didSet blocks for our properties, whenever the user types a letter into the search bar, the value of searchedUniversities property changes and triggers the didSet block to reload the table view. That way, the user can see searched universities in the table view as they change.
I hope this article was helpful. Property Observers are simple but powerful concepts to be utilized in iOS applications. Stay healthy.