Sebenarnya jawaban di atas benar-benar hebat, tetapi mereka kehilangan beberapa perincian untuk apa yang dibutuhkan banyak orang dalam proyek klien / server yang terus dikembangkan. Kami mengembangkan aplikasi sementara backend kami terus berkembang dari waktu ke waktu, yang berarti beberapa kasus enum akan mengubah evolusi itu. Jadi kita memerlukan strategi decoding enum yang dapat men-decode array enum yang berisi kasus yang tidak diketahui. Kalau tidak, decoding objek yang berisi array hanya gagal.
Apa yang saya lakukan cukup sederhana:
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: Sembunyikan implementasi> Jadikan Koleksi
Menyembunyikan detail implementasi selalu merupakan ide yang bagus. Untuk ini, Anda akan memerlukan sedikit lebih banyak kode. Caranya adalah dengan menyesuaikan DirectionsListuntuk Collectiondan membuat internal Anda listarray yang pribadi:
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)
}
}
Anda dapat membaca lebih lanjut tentang menyesuaikan dengan koleksi khusus dalam posting blog ini oleh John Sundell: https://medium.com/@johnsundell/creating-custom-collections-in-swift-a344e25d0bb00