POP would be a great way to define the interface for my object, while allowing me to provide a mock object for running in the simulator.
(I'm dealing with Bluetooth here - but this has more general application)
However - @ObservableObject doesn't seem compatible with protocol definition - it seems unable to detect that the protocol inherits from ObservableObject.
Is there a way to make this work?
all the options I'm trying here fail:
protocol Foo {}
protocol ObservableFoo: Foo,ObservableObject {}
struct TestView: View {
@ObservedObject var foo:Foo
@ObservedObject var anyFoo:any Foo
@ObservedObject var observableFoo:ObservableFoo
@ObservedObject var obsAndFoo:Foo & ObservableObject
var body: some View {
Text("Hello, World!")
}
}
We have a custom property wrapper specifically for this, called @Store. Our implementation (Swift 5.5+) can be found here, which is in turn based on the (Swift 5.3-5.4) implementation from XUI here.
The idea is that XUI provides a version of ObservableObject with no associated types:
public protocol AnyObservableObject: AnyObject {
var objectWillChange: ObservableObjectPublisher { get }
}
The default implementation of ObservableObject statisfies this protocol. To avoid warnings that any MyProtocol does not conform to AnyObservableObject, there is no constraint on the generic type, and instead it's conditionally downcasted:
if let observable = wrappedValue as? AnyObservableObject {
// observable.objectWillChange is now a usable publisher
} else {
assertionFailure(
"Only use the Store property wrapper with objects conforming to AnyObservableObject."
)
}
Once you have the usable objectWillChange in the first branch, you can observe that directly.