The problem is not that you can’t access the id as a concrete type (String?
): e.g. try:
let firstID/*: String?*/ = models[0].id
The problem here is that the ForEach initializer expects of a collection of an Identifiable-conforming type, but models
is an array of any Model
. This “any” (“existential”) type, as other “any” types, can’t conform to other protocols. Thus, any Model
cannot conform to Identifiable
. What you can do instead is create a wrapper type yourself which can conform to Identifiable
:
struct AnyModel: Model {
private var _model: any Model
init(_ model: some Model) {
_model = model // Automatically casts to “any” type
}
var id: String? {
get { _model.id }
set { _model.id = newValue }
}
}
Then, you can use this wrapper type where you’d use the any type. E.g. models
would now have a type [AnyModel]
. This is a common strategy in Swift (see AnyHashable
) and SwiftUI (see AnyView
).