En realidad, las respuestas anteriores son realmente geniales, pero les faltan algunos detalles de lo que mucha gente necesita en un proyecto cliente / servidor desarrollado continuamente. Desarrollamos una aplicación mientras nuestro backend evoluciona continuamente con el tiempo, lo que significa que algunos casos de enumeración cambiarán esa evolución. Por lo tanto, necesitamos una estrategia de decodificación de enumeración que sea capaz de decodificar matrices de enumeraciones que contienen casos desconocidos. De lo contrario, la decodificación del objeto que contiene la matriz simplemente falla.
Lo que hice es bastante simple:
enum Direction: String, Decodable {
case north, south, east, west
}
struct DirectionList {
let directions: [Direction]
}
extension DirectionList: Decodable {
public init(from decoder: Decoder) throws {
var container = try decoder.unkeyedContainer()
var directions: [Direction] = []
while !container.isAtEnd {
// Here we just decode the string from the JSON which always works as long as the array element is a string
let rawValue = try container.decode(String.self)
guard let direction = Direction(rawValue: rawValue) else {
// Unknown enum value found - ignore, print error to console or log error to analytics service so you'll always know that there are apps out which cannot decode enum cases!
continue
}
// Add all known enum cases to the list of directions
directions.append(direction)
}
self.directions = directions
}
}
Bonificación: Ocultar implementación> Convertirla en una colección
Ocultar detalles de implementación es siempre una buena idea. Para esto necesitarás un poco más de código. El truco consiste en conformar DirectionsList
a Collection
y hacer que su interior list
serie privada:
struct DirectionList {
typealias ArrayType = [Direction]
private let directions: ArrayType
}
extension DirectionList: Collection {
typealias Index = ArrayType.Index
typealias Element = ArrayType.Element
// The upper and lower bounds of the collection, used in iterations
var startIndex: Index { return directions.startIndex }
var endIndex: Index { return directions.endIndex }
// Required subscript, based on a dictionary index
subscript(index: Index) -> Element {
get { return directions[index] }
}
// Method that returns the next index when iterating
func index(after i: Index) -> Index {
return directions.index(after: i)
}
}
Puede leer más sobre la conformidad con las colecciones personalizadas en esta publicación de blog de John Sundell: https://medium.com/@johnsundell/creating-custom-collections-in-swift-a344e25d0bb0