Context
I have a protocol Component with an Object conforming to Category as its associated type. I also have a generic SwiftUI ComponentsView, in which I'd like to use the Category of the given Component inside a ForEach. However, I get the following Compiler Error:
Generic struct 'ForEach' requires that 'C.C.AllCases' conform to 'RandomAccessCollection'
Code
protocol Component {
associatedtype C: Category
}
protocol Category: Identifiable, CaseIterable {
var name: String { get }
}
struct ComponentsView<C: Component>: View {
var body: some View {
ForEach(C.C.allCases) { category in
Text(category.name)
}
}
}
Question
- What causes the Compiler Error and how can I solve it?
From my understanding, the allCases variable of CaseIterable returns an Array, which already conforms to RandomAccessCollection.
CodePudding user response:
In CaseIterable AllCases is defined with a default value:
associatedtype AllCases : Collection = [Self] where Self == Self.AllCases.Element
but that's all it is, a default value. In ComponentsView:
struct ComponentsView<C: Component>: View {
var body: some View {
ForEach(C.C.allCases) { category in
Text(category.name)
}
}
}
All the compiler sees is a Component
protocol Component {
associatedtype C: Category
}
that has a Category that is CaseIterable:
protocol Category: Identifiable, CaseIterable {
var name: String { get }
}
But there is no information about its associated type. So, it could be an array, or it could be another type of collection.
Adding a constraint on Component.C solves the issue:
protocol Component {
associatedtype C: Category where C.AllCases: RandomAccessCollection
}
