I've been using protocols to help model a hierarchy of different object types. As I try to convert my app to use SwiftUI, I'm finding that protocols don't work with the ObservableObject that you need for SwiftUI models. I wonder if there are some techniques to get around this, or if people are just giving up on "protocol oriented programming" when describing their SwftUI models? There is example code below. The main problem is that it seems impossible to have a View that with an model of protocol `P1` that conditionally shows a subview with more properties if that model also conforms to protocol `P2`.
For example, I'm creating a drawing/painting app, so I have "Markers" which draw on the canvas. Markers have different properties like color, size, shape, ability to work with gradients. Modeling these properties with protocols seems ideal. You're not restricted with a single inheritance class hierarchy. But there is no way to test and down-cast the protocol...
protocol Marker : ObservableObject {
var name: String { get set }
}
protocol MarkerWithSize: Marker {
var size: Float { get set }
}
class BasicMarker : MarkerWithSize {
init() {}
@Published var name: String = "test"
@Published var size: Float = 1.0
}
struct ContentView<MT: Marker>: View {
@ObservedObject var marker: MT
var body: some View {
VStack {
Text("Marker name: \(marker.name)")
if marker is MarkerWithSize {
// This next line fails
// Error: Protocol type 'MarkerWithSize' cannot conform to 'MarkerWithSize'
// because only concrete types can conform to protocols
MarkerWithSizeSection(marker: marker as! MarkerWithSize)
}
}
}
}
struct MarkerWithSizeSection<M: MarkerWithSize>: View {
@ObservedObject var marker: M
var body: some View {
VStack {
Text("Size: \(marker.size)")
Slider(value: $marker.size, in: 1...50)
}
}
}
Thoughts?