Native Observers. How Cool!

Today I learned about a nifty little language feature in Swift that had somehow escaped my attention in these last weeks of exploration. The feature is called Property Observers and you can find them here in Apple's official Swift docs.

Property Observers are essentially lifecycle methods for properties on an object. They might more verbosely be called Property Set Observers since they are only available to watch a property being set. There are two observers, willSet and didSet. If you have worked in any language or framework with object lifecycle methods these should be immediately self explanatory. If not, it can be explained as follows:

Property Observers are methods which are available to be set on any Object's property. When defined, the willSet method will be called immediately before a new value is assigned to the property and the didSet will be called immediately after this assignment.

Let's look at an example.

struct MyStruct {
    static var someProperty = "initial value" {
        willSet(newValue) {
            print("The current value is \(someProperty).")
            print("The new value is \(newValue)")
        }
        didSet {
            print("The current value is now \(someProperty)")
        }
    }
}

MyStruct.someProperty = "some other value"
// This will print:
//     "The current value is initial value"
//     "The new value is some other value"
//     "The current value is now some other value"

Now you might be asking yourself "Why would I use this instead of a regular old property setter?" and the answer is an emphatic "You wouldn't!". Or at least, you shouldn't if you need to compute the value of the assignment. In fact, you can't even create a Property Observer for a computed property. Meaning if you define a set for your property, you cannot define willSet or didSet.

But, if you're property isn't being computed and some other part of your program depends on it and needs to update according to its changes, then this offers a very tidy way to notify that part of your program before the change occurs and after. Imagine you have a struct that holds a value for your users income. When this value is updated you have a view that must do lots of calculations and network calls with the new value before redrawing its content. Well, using a willSet you can have your controller send the message to start displaying the loading indicator and the didSet can send the message to start running the calculations and making the requests.

Could you do all of this in a set? Absolutely, but if you aren't actually computing the value of the assignment this seems to be a little indirect and using a PropertyObserver seems like a much more obvious and readable choice.