So, that seems great, but this is starting to get really hairy. Not only do we have to be precise with our application of the @Published
property wrapper to make sure each individual feature observes only the state it cares about, but we also need to be very precise in subscribing to child state changes that should cause the parent feature to re-render.
In practice this is incredibly difficult to do perfectly, and so you are more likely to just throw you hands up in the air and decide to subscribe to all state changes of the child feature even though you know it is not efficient to do so. And at the end of the day, SwiftUI simply does not have a good answer for this kind of problem when nesting observable objects. And this goes for holding onto observable objects directly in another observable object, as we have done with the AppModel
, but also when holding onto other observable objects in an optional, or in an array, or a dictionary, or any other kind of data structure.
So, that was a quick tour of the past observation tools that SwiftUI gave us prior to iOS 17 and Swift 5.9. They were powerful, but they were also very easy to use incorrectly, either leading you to observe too much state causing inefficient views, or observe too little state causing glitchy views.
And these are exactly the problems that led to the creation of the new Observation framework in Swift, which is available in Swift 5.9 and iOS 17. It is a pure Swift framework, having nothing to do with any of Apple’s proprietary platforms, but of course its #1 use case is SwiftUI.
It allows one to implement features in the naive way that we started with, and it will “just work”. You get to use plain, mostly un-adorned reference types and do not have to explicitly mark the fields that need to be observed. You get to hold onto the model in your view as a simple let
or @State
property. And somehow, magically, the view will properly observe the changes inside the class. And it even works fantastically with nested classes.
It’s pretty incredible to see, so let’s check it out.