While developing a universal app with the updated SwiftUI framework, I found that @Published decorators do not function as intended in objects inheriting from NSManagedObject class.
What’s Expected & What’s Broken
What’s exactly the expected behaviour anyway? We know that —
- Objects conforming to
ObservableObjectprotocol can have variables marked with@Published. SwiftUI views that depends on an observable object instance will update when a published variable receives a new value. - Objects inheriting from
NSManagedObjectclass can have variables marked with@NSManaged. SwiftUI views that depends on an NSManagedObject will update when the@NSManagedvariable receives a new value in the managed context. - ObservableObject is RAM only; NAManagedObject is written to the Core Data context and optionally saved to disk.
- Objects inheriting from
NSManagedObjectclass automatically conforms toObservableObject. So they should be able to mark variables with either@Publishedor@NSManagedto have views updated automatically. You will want to use@Publishedto update variables that update frequently but needs no disk persistence.
But here’s what is broken: Published variables in NSManagedObject instances do not update SwiftUI views as expected.
The Cause
As discussed on Stack Overflow, this is likely a bug on Apple’s end. There have been discussions since September 2019 but this problem still exists today. Somehow the implementation of ObservableObject protocol for NSManagedObject doesn’t trigger objectWillChange.send() method.
The Workaround
Since the objectWillChange.send() method doesn’t get triggered, the workaround is to simply trigger it manually.
Consult to Jesse Spencer’s answer in the same thread. Or the answer of Anthony’s.