Search code examples
swiftswiftuiswiftui-foreach

Swift - enum conformance return allCases of different types


I got The compiler is unable to type-check this expression in reasonable time; try breaking up the expression into distinct sub-expressions I know that's because the compiler can't resolve the type, what's can make it more simple for the compiler?

Also, always looking to do better, is there a better approach to assign a value to a data model who shares the same protocol conformance?

  protocol RelationshipType:CaseIterable {
        
        associatedtype relationShip
    }

enum RomanticRelationType:String, RelationshipType {
       
    
        case couple, married, engaged
        
        var title: String {
            
            switch self {
            case .couple:
                return "Couple"
            case .married:
                return "Married"
            case .engaged:
                return "Engaged"
            }
        }
        var priority: Int {
            switch self {
            case .couple:
                return 3
            case .engaged:
                return 2
            case .married:
                return 1
            }
        }
        
  }

extension RomanticRelationType {
    typealias relationShip = RomanticRelationType
    
    static var allCases: [RomanticRelationType] {
        return [.couple, .married, .engaged]
    }
}

var relationships:any RelationshipType {
    
    switch selectedRelationType {
    case .personal:
        return PersonalRelationType.allCases as! (any RelationshipType)
    case .professional:
        return ProfessionalRelationType.allCases as! (any RelationshipType)
    case .romantic:
        return RomanticRelationType.allCases as! (any RelationshipType)
    }

    
}

            Picker("Type", selection: $relationsVM.selectedRelation.relationship) {
                ForEach(relationsVM.relationships, id: \.self) { relationType in
                    Text(relationType.title)
                }
            }.pickerStyle(.menu)

Solution

  • Your bug is this (and the related lines):

        return PersonalRelationType.allCases as! (any RelationshipType)
    

    This is invalid. [RomanticRelationType] does not conform to RelationshipType. An array is not the same thing as an element. I believe you meant this:

    var relationships:[any RelationshipType] {
        switch selectedRelationType {
        case .personal:
            return PersonalRelationType.allCases
        case .professional:
            return ProfessionalRelationType.allCases
        case .romantic:
            return RomanticRelationType.allCases 
        }
    }