When I add the following line to my view, I get the error from compiler. Project won't compile now. I got this line of code from the 'Search with geocode' sample.
@StateObject private var inspectedOverlay = GraphicsOverlay()
Generic struct 'StateObject' requires that 'GraphicsOverlay' conform to 'ObservableObject'
Solved! Go to Solution.
It is recommended to put these reference type objects in a viewmodel-like object that conforms to ObservableObject protocol like below. See an Apple example here.
class Model: ObservableObject {
let graphicsOverlay = GraphicsOverlay()
// ... other properties below
}
The reasoning behind is that a graphics overlay isn't "a type of object with a publisher that emits before the object has changed. (from Apple doc)". In other words, it doesn't drive an UI update with published states, thus is semantically wrong to be an ObservableObject.
However, as of today there isn't a property wrapper in SwiftUI that means "I want to keep an object unchanged between view re-computation, but the object doesn't effectively need to be observable." StateObject kind of works, but is not perfect. Moreover, Apple may moved away from ObservableObject in a future release (pitch).
With that said, you can still conform the GraphicsOverlay type to ObservableObject protocol yourself, such as
// somewhere in your code...
extension GraphicsOverlay: ObservableObject {}
then you can hold the object as an @StateObject without issue.
Finally, the reason that the sample viewer doesn't get this error but your code does, is that in the Search with geocode sample, it imported the toolkit, which in 200.0.0-beta added a few ObservableObject conformances like above. We are considering removing this conformance in 200.1.0.
It is recommended to put these reference type objects in a viewmodel-like object that conforms to ObservableObject protocol like below. See an Apple example here.
class Model: ObservableObject {
let graphicsOverlay = GraphicsOverlay()
// ... other properties below
}
The reasoning behind is that a graphics overlay isn't "a type of object with a publisher that emits before the object has changed. (from Apple doc)". In other words, it doesn't drive an UI update with published states, thus is semantically wrong to be an ObservableObject.
However, as of today there isn't a property wrapper in SwiftUI that means "I want to keep an object unchanged between view re-computation, but the object doesn't effectively need to be observable." StateObject kind of works, but is not perfect. Moreover, Apple may moved away from ObservableObject in a future release (pitch).
With that said, you can still conform the GraphicsOverlay type to ObservableObject protocol yourself, such as
// somewhere in your code...
extension GraphicsOverlay: ObservableObject {}
then you can hold the object as an @StateObject without issue.
Finally, the reason that the sample viewer doesn't get this error but your code does, is that in the Search with geocode sample, it imported the toolkit, which in 200.0.0-beta added a few ObservableObject conformances like above. We are considering removing this conformance in 200.1.0.
That makes sense. I ended up putting it into global view model object so I can add graphics from anywhere in my app. However, the sample threw me off for a bit.
Thanks for the clarification.