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:
- ObservableObject as StateObject in struct App
- Make these objects as environmentalObject across views
- 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)
}
}
}
}