Getting property changing notifications using property observers
It’s common to want to know when a property’s value changes. Perhaps you want to update the value of another property or update some UI element. In Objective-C, this was often accomplished by writing your own getter and setter or using Key-Value Observing (KVO). However, in Swift, we have native support for property observers.
Getting ready
To examine property observers, we should create an object with a property that we want to observe. Let’s create an object that manages users and a property that holds the current user’s name.
Enter the following code into a new playground:
class UserManager {
var currentUserName: String = "Emmanuel Goldstein"
}
We want to present some friendly messages when the current user changes. We’ll use property observers to do this.
How to do it...
Let’s get started:
- Amend the
currentUserNameproperty definition so that it looks as follows:class UserManager { var currentUserName: String = "Guybrush Threepwood" { willSet (newUserName) { print("Goodbye to \(currentUserName)") print("I hear \(newUserName) is on their way!") } didSet (oldUserName) { print("Welcome to \(currentUserName)") print("I miss \(oldUserName) already!") } } } - Create an instance of
UserManager, and change the current username. This will generate friendly messages:let manager = UserManager() manager.currentUserName = "Elaine Marley" // Goodbye to Guybrush Threepwood // I hear Elaine Marley is on their way! // Welcome to Elaine Marley // I miss Guybrush Threepwood already! manager.currentUserName = "Ghost Pirare LeChuck" // Goodbye to Elaine Marley // I hear Ghost Pirare LeChuck is on their way! // Welcome to Ghost Pirare LeChuck // I miss Elaine Marley already!
How it works...
Property observers can be added within curly brackets after the property declaration, and there are two types – willSet and didSet.
The willSet observer will be called before the property is set and provides the value that will be set on the property. This new value can be given a name within brackets – for example, newUserName:
willSet (newUserName) {
//...
}
The didSet observer will be called after the property is set and provides the value that the property had before being set. This old value can be given a name within brackets – for example, oldUserName:
didSet (oldUserName) {
//...
}
There’s more...
The new value and old value that are passed into the property observers have implicit names, so there is no need to explicitly name them. The willSet observer is passed a value with an implicit name of newValue, and the didSet observer is passed a value with an implicit name of oldValue.
Therefore, we can remove our explicit names and use the implicit value names:
class UserManager {
var currentUserName: String = "Guybrush Threepwood" {
willSet {
print("Goodbye to \(currentUserName)")
print("I hear \(newValue) is on their way!")
}
didSet {
print("Welcome to \(currentUserName)")
print("I miss \(oldValue) already!")
}
}
}
See also
Further information about property observers can be found in Apple’s documentation on the Swift language at http://swiftbook.link/docs/properties.