Type 'any Identifiable<UUID>' cannot conform to 'Identifiable'

Hello,

I am trying to have an array of ViewModel in a ForEach, but the following error is thrown:

Type 'any ViewModel' cannot conform to 'Identifiable'

A similar error would happen if instead of [any ViewModel], I'd have [any Identifiable<UUID>]:

Type 'any Identifiable < UUID >' cannot conform to 'Identifiable'

I am not sure I understand why this happens as ViewModel is tied to Identifiable<UUID>, so the elements of the collection passed to ForEach will always have the same type of id.

Can somebody please explain to me what I'm missing?

Thank you.

protocol ViewModel: Identifiable<UUID>, ObservableObject {}

class ViewModel1: ViewModel {
    let id = UUID()
}

class ViewModel2: ViewModel {
    let id = UUID()
}

let viewModels: [any ViewModel] = [
    ViewModel1(),
    ViewModel2()
]

struct ListScreen: View {
    var body: some View {
        List {
            ForEach(viewModels) { model in // <- Error happens here
                  // ...
            }
        }
    }
}

Unfortunately existential types (such as any ViewModel) don't generally conform to the protocols they're composed of, any Error being the exception for now. But you can work around this by introducing a wrapper type such as:

struct AnyViewModel: Identifiable {
    var base: any ViewModel
    var id: UUID { base.id }
}

and passing around an array of those instead.

1 Like

It’s annoying but can be sidestepped by using a “trampoline” on the protocol itself: Protocol as a type cannot conform to the protocol itself - #3 by jjrscott