In trying to make a view that can show a table of listings that can show items with the same elements (just a name so far), I've gotten myself stuck in a corner of Swift that I thought I understood but apparently don't.
I created a protocol, NamedModel, that is marked as Identifiable, Hashable and Equatable.
protocol NamedModel : Identifiable, Equatable, Hashable {
var name: String { get }
var id: UUID { get }
}
extension NamedModel {
static func == (lhs: Self, rhs: Self) -> Bool {
lhs.id == rhs.id &&
lhs.name == rhs.name
}
}
One model type I created is the AppModel:
struct AppModel: NamedModel {
var name: String
var id = UUID()
}
I created a protocol for my view models to conform to that includes a property that's an array of NamedModel:
protocol ListViewDataProvider {
var items: [any NamedModel] { get set }
...
}
I created a view model class for my Applications view that conforms to the ListViewDataProvider protocol.
@Observable class ApplicationsListModel: ObservableObject, ListViewDataProvider {
var items: [any NamedModel] = []
...
}
In my view, I have a property, dataProvider, that conforms to that ListViewDataProvider protocol, and uses its items var for populating the table:
struct ApplicationsListView: View {
var dataProvider: ListViewDataProvider
@State private var selectedAppID: UUID? = nil
...
Table(dataProvider.items, selection: $selectedAppID) {
TableColumn("Applications") { app in
Text(app.name)
}
...
}
}
On the line declaring the TableColumn, I get an error: Type 'TableForEachContent<[any NamedModel]>.TableRowValue' (aka 'any NamedModel') cannot conform to 'Identifiable'
I don't understand why this is occurring, as I've marked the NamedModel type as conforming to Identifiable. I'm hoping somebody can help me understand what I'm doing wrong. I'd like to be able to reuse some views with common characteristics in this app.