How to use Observation to actually observe changes to a property

Not really, the big thing is that you need to use a reference-counted type in order to detect the “thing you are observing was deinitialized” case. Also, I needed to have a separate “streaming is done” variable to signal when the continuation should be finished.

Just found this solution. It looks pretty nice to me.

1 Like

I use:

  1. ObservableObject as StateObject in struct App
  2. Make these objects as environmentalObject across views
  3. I track these objects values by combine in viewModels as well

Now I want to refactor them into @Observable and got the same confusing how to track these object's values outside of views if I want to make 3 works.

There’s a migration guide: Migrating from the Observable Object protocol to the Observable macro | Apple Developer Documentation

1 Like

I wrote an extension to make it work just like combine

extension Observable where Self: AnyObject {
    func publisher<T>(keyPah: KeyPath<Self, T>) -> CurrentValueSubject<T, Never> {
        
        let initValue = self[keyPath: keyPah]
        
        let subject = CurrentValueSubject<T, Never>(initValue)
        
        observableTracking(object: subject) { [weak self, weak subject] in
            if let self {
                let value = self[keyPath: keyPah]
                subject?.send(value)
            }
        }
        
        return subject
    }
    
    func observableTracking<T>(object: AnyObject?, apply: @escaping () -> T) {
        _ = Observation.withObservationTracking {
            apply()
        } onChange: { [weak object, weak self] in
            guard object != nil else { return }
            DispatchQueue.main.async {
                self?.observableTracking(object: object, apply: apply)
            }
        }

    }
}