Context
Hey there, I am currently working with Protocols
in SwiftUI
and encountered a Problem.
I have an Array
of a Protocol Type
and would like to use it to populate a SwiftUI ForEach View
. However, this throws the following error:
Type 'any Component' cannot conform to 'Identifiable'
Code
protocol Component: ObservableObject, Identifiable {
var name: String { get }
}
struct ComponentsView: View {
var body: some View {
ForEach(components) { component in // Error in this Line
Text(component.name)
}
}
private var components: [any Component] {
return []
}
}
Question
- How can I populate my
SwiftUI ForEach View
with theArray
ofComponents
?
The latest version of Swift allows you to create an array of "existential" typed values (any Component
), but the limitation still exists that the existential/protocol type does not itself conform to the protocol.
That means, for the purposes of the ForEach
, components are not known at compile time to be Identifiable
. You can work around that by specifying the id
property explicitly:
struct ComponentsView: View {
var body: some View {
ForEach(components, id: \.name) { component in
Text(component.name)
}
}
If Component
must be a reference type anyway (to get ObservableObject
conformance), another alternative would be to use a base class rather than a protocol (or a base class and a protocol). What you do here depends on the larger requirements of your code.