Na verdade, as respostas acima são realmente ótimas, mas faltam alguns detalhes para o que muitas pessoas precisam em um projeto cliente / servidor desenvolvido continuamente. Desenvolvemos um aplicativo enquanto nosso back-end evolui continuamente ao longo do tempo, o que significa que alguns casos de enum mudarão essa evolução. Portanto, precisamos de uma estratégia de decodificação de enumeração capaz de decodificar matrizes de enumerações que contêm casos desconhecidos. Caso contrário, a decodificação do objeto que contém a matriz simplesmente falha.
O que eu fiz é bem simples:
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
}
}
Bônus: ocultar implementação> Criar uma coleção
Ocultar os detalhes da implementação é sempre uma boa ideia. Para isso, você precisará de um pouco mais de código. O truque consiste em conformar DirectionsList
a Collection
e faça a sua interna list
variedade 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)
}
}
Você pode ler mais sobre a conformidade com coleções personalizadas nesta postagem de blog de John Sundell: https://medium.com/@johnsundell/creating-custom-collections-in-swift-a344e25d0bb0