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
ObservableObject
protocol 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
NSManagedObject
class can have variables marked with@NSManaged
. SwiftUI views that depends on an NSManagedObject will update when the@NSManaged
variable 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
NSManagedObject
class automatically conforms toObservableObject
. So they should be able to mark variables with either@Published
or@NSManaged
to have views updated automatically. You will want to use@Published
to 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.