SwiftUI Protocols as Type: Value cannot conform to `Identifiable'; only struct/enum/class types can conform to protocols

Viewed 898

Hope you all had a wonderful holidays. Happy new year!

So, I'm using protocols as Type:

protocol Protocol_A_Or_B { }
protocol ProtocolA: Protocol_A_Or_B, Identifiable, Hashable, CaseIterable { }
protocol ProtocolB: Protocol_A_Or_B, Identifiable, Hashable, CaseIterable { }

I removed all variables and functions from protocols as I consider those are not relevant for the issue I'm facing.

I created a couple of enums that implement either ProtocolA or ProtocolB. Also, I have a "main enum" that has a method that returns an array of objects that either implements ProtocolA or ProtocolB, for this, ProtocolA and ProtocolB have a "parent" protocol (Protocol_A_Or_B).

enum MainEnum_: Int, Identifiable, Hashable, CaseIterable {
    case One
    case Two
    case Three
    case Four
    case Five
    
    var id:Int { rawValue }
    
    var aOrBEnumArray: [Protocol_A_Or_B] {
        switch self {
        case .One:
            return EnumTypeA.allCases
        case .Two:
            return EnumTypeB.allCases
        default:
            return []
        }
    }
}

enum EnumTypeA: Int, ProtocolA {
    case Option1
    case Option2
    case Option3
    
    var id:Int { rawValue } 
}

enum EnumTypeB: Int, ProtocolB {
    case OptionA
    case OptionB
    case OptionC
    
    var id:Int { rawValue }
}

So far, so good. But when I try to send an array of objects that implement Protocol_A_Or_B, I get the following errors:

Value of protocol type 'Protocol_A_Or_B' cannot conform to 'Hashable'; only struct/enum/class types can conform to protocols

Value of protocol type 'Protocol_A_Or_B' cannot conform to 'Identifiable'; only struct/enum/class types can conform to protocols

Here's a mock of the View where I'm using the objects. I get the errors in the lines of code TheContentView2(data: arrayEnumTypeA) and TheContentView2(data: arrayEnumTypeB).

struct EnumProtocolsTest: View {
    var arrayEnumTypeA: [Protocol_A_Or_B] = MainEnum_.One.aOrBEnumArray
    var arrayEnumTypeB: [Protocol_A_Or_B] = MainEnum_.Two.aOrBEnumArray
    
    var body: some View {
        VStack {
            ScrollView(.horizontal, showsIndicators: false) {
                HStack {
                    TheContentView2(data: MainEnum_.allCases) { item in
                        Text("\(item.name)")
                            .padding()
                            .background(Color.purple)
                    }
                }
            }
            
            ScrollView(.horizontal, showsIndicators: false) {
                HStack {
                    TheContentView2(data: arrayEnumTypeA) { item in
                        Text("\(item.id)")
                            .padding()
                            .background(Color.purple)
                    }
                }
            }
            
            ScrollView(.horizontal, showsIndicators: false) {
                HStack {
                    TheContentView2(data: arrayEnumTypeB) { item in
                        Text("\(item.id)")
                            .padding()
                            .background(Color.purple)
                    }
                }
            }
        }
    }
}

So, for what I understand, I think the error is related with the custom view I have (TheContentView2), as it has to receive an array of objects that implements Identifiable and Hashable.

struct TheContentView2<Data: RandomAccessCollection, ElementView: View>: View where Data.Element: Identifiable, Data.Element: Hashable {
    var data: Data
    var itemView: (Data.Element) -> ElementView
    
    var body: some View {
        ForEach(data) { item in
            itemView(item)
                .padding()
                .background(Color.purple)
        }
    }
}

I cannot add my protocols as part of this view's definition/signature, but if it's incorrect then I can request the change.

Hope you can help me. I don't know how I can send an array of objects that implement the parent protocol (Protocol_A_Or_B). Not sure what am I missing in the protocol definition or in the custom view's signature.

Thanks!!!

0 Answers
Related