Estoy tratando de hacer que la enumeración con el valor asociado se ajuste a CaseIterable, RawRepresentable. Estoy bien con algunos valores predeterminados para valores asociados al inicializar por rawValue.
enum GenresAssociated: CaseIterable, RawRepresentable, Equatable { case unknown(String) case blues(String) case classical(String) // Implementing CaseIterable typealias AllCases = [GenresAssociated] // Enums can have no storage, but the class they are in CAN. Note 'static' in declaration static var allCases: [GenresAssociated] = [.unknown(""), .blues(""), .classical("")] typealias RawValue = Int var rawValue: Int { // MARK: This causes a crash for unknown reason return GenresAssociated.allCases.firstIndex(where: { if case self = $0 { return true } else { return false } } ) ?? 0 } init?(rawValue: Int) { guard GenresAssociated.allCases.indices.contains(rawValue) else { return nil } self = GenresAssociated.allCases[rawValue] } }¿Hay alguna forma de hacerlo sin cambiar manualmente por todos los casos, es decir, sin dicho código:
typealias RawValue = Int var rawValue: Int { switch self { case .unknown: return 0 case .blues: return 1 case .classical: return 2 } }Lo notable es que un código muy similar funciona bien, por ejemplo
enum EnumWithValue { case one(NSString!), two(NSString!), three(NSString!) } let arrayOfEnumsWithValues: [EnumWithValue] = [.one(nil), .two(nil), .three("Hey")] if let index = arrayOfEnumsWithValues.firstIndex(where: { if case .two = $0 { return true }; return false }) { print(".two found at index \(index)") //prints ".two found at index 1" }¡Finalmente lo conseguí para trabajar con Mirror !
var rawValue: Int { let selfCaseName = Mirror(reflecting: self).children.first!.label! return GenresAssociated.allCases.firstIndex(where: { (genre) in let switchingCaseName = Mirror(reflecting: genre).children.first!.label! return switchingCaseName == selfCaseName })! }No te preocupes por la fuerza que se desenvuelve, aquí es seguro.
Este parámetro funcionará con enumeraciones que contengan tanto casos de valores sin procesar como casos con valores asociados:
var caseName: String { let result = String(describing: self) let assocValName = Mirror(reflecting: self).children.first?.label ?? "failed" return !result.contains("(") ? result : assocValName }