Using Swift 5.7 we're trying to use protocols for testing and mocking in our SwiftUI App.
With any
and some
we're able to hold a heterogeneous list of protocols with self constraints which works perfectly. What we're running into now is that we can't undox the any Protocol
into a concrete type for the view.
Here's a basic example:
protocol ItemProtocol: ObservableObject {
var id: String { get }
}
struct ListSection {
var id: Int
let title: String
let items: [any ItemProtocol]
}
protocol ViewModelProtocol: ObservableObject {
var sections: [ListSection] { get }
}
struct MyView<T: ViewModelProtocol>: View {
@ObservedObject
var viewModel: T
init(viewModel: T) {
self.viewModel = viewModel
}
var body: some View {
List(viewModel.sections, id: \.id) { section in
Section {
ForEach(section.items, id: \.id) { item in
RowView(item: item)
// create view for some ItemProtocol
Text("Hello Item")
}
} header: {
Text(section.title)
}
}
}
}
struct RowView<T: ItemProtocol>: View {
@ObservedObject
var item: T
init(item: T) {
self.item = item
}
var body: some View {
Text("Row View")
}
}
This will result in an error:
Type 'any ItemProtocol' cannot conform to 'ItemProtocol'
I had hoped that the any ItemProtocol
would be unboxed to it's concrete type and a concrete type of View would be created.