How to manually subscribe to changes of SwiftUI's @Observable objects
Learn how to use the withObservationTracking method of the Observation framework.
22 Aug 2023 · 3 min read
At WWDC23, Apple released a new Observation framework for SwiftUI. We already covered the basics in this article on how to migrate from ObservableObject to the Observation macro in SwiftUI.
In this article, we'll dive a bit deeper and look at how we can subscribe to changes of @Observable objects manually. Let's get started.

When working with @Observable marked objects within SwiftUI views, SwiftUI automatically takes care of tracking changes und updating views when needed. But there are still use cases, where we need to manually subscribe to those changes, for example to trigger actions such as dismissing a view or to trigger view unrelated actions such as persisting data o.s.
When working with @Published properties, we have the opportunity to access the Combine publisher for a property by prefixing it with an $ to suscribe to property changes, for example:
class UserViewModel: ObservableObject {@Published var name = ""func subscribeToChanges() {cancellable = viewModel.$name.sink { [weak self] newValue inprint(newValue)}}}
With the Observation framework, we can't do that anymore. For tracking changes outside of SwiftUI, it provides the withObservationTracking(_:onChange:) method.
Let's look at an example:
@Observableclass UserViewModel {var name: String = ""func subscribeToChanges() {withObservationTracking {_ = name} onChange: { [weak self] inguard let self else { return }print(self.name)}}}
As we can see above, the functions takes two closures as its parameters: apply and onChange. The apply closure contains which properties to track and the onChange closure is invoked when the value of a property changes.
There are two important differences to the mentioned Combine publisher approach though:
- The onChange closure is called right before the new values are set, so we don't have access to the new values in the onChange closure
- The onChange method is only called once - when one of the tracked values changes - and is never called again.
Unfortunately, the Observation framework does currently not provide an API to be able to continuously subscribe to changes and getting their new values. Since the Observation framework is currently in beta, the framework will hopefully provide this functionality in the future.

Newsletter
Like to support my work?
Say hi
Related tags
Articles with related topics
Latest articles and tips