En fait, les réponses ci-dessus sont vraiment excellentes, mais il leur manque quelques détails sur ce dont beaucoup de gens ont besoin dans un projet client / serveur développé en permanence. Nous développons une application pendant que notre backend évolue continuellement au fil du temps, ce qui signifie que certains cas d'énumération changeront cette évolution. Nous avons donc besoin d'une stratégie de décodage enum capable de décoder des tableaux d'énumérations contenant des cas inconnus. Sinon, le décodage de l'objet qui contient le tableau échoue tout simplement.
Ce que j'ai fait est assez 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
}
}
Bonus: Masquer la mise en œuvre> En faire une collection
Masquer les détails de l'implémentation est toujours une bonne idée. Pour cela, vous aurez besoin d'un peu plus de code. L'astuce est de se conformer DirectionsList
à Collection
et rendre votre intérieur list
tableau privé:
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)
}
}
Vous pouvez en savoir plus sur la conformité aux collections personnalisées dans cet article de blog de John Sundell: https://medium.com/@johnsundell/creating-custom-collections-in-swift-a344e25d0bb0