ที่จริงแล้วคำตอบข้างต้นนั้นยอดเยี่ยมจริงๆ แต่พวกเขาขาดรายละเอียดบางอย่างสำหรับสิ่งที่หลาย ๆ คนต้องการในโครงการไคลเอนต์ / เซิร์ฟเวอร์ที่พัฒนาอย่างต่อเนื่อง เราพัฒนาแอพในขณะที่แบ็กเอนด์ของเราวิวัฒนาการอย่างต่อเนื่องเมื่อเวลาผ่านไปซึ่งหมายความว่าบางกรณี Enum จะเปลี่ยนวิวัฒนาการที่ ดังนั้นเราต้องการกลยุทธ์การถอดรหัส enum ที่สามารถถอดรหัสอาร์เรย์ของ enums ที่มีกรณีที่ไม่รู้จัก มิฉะนั้นการถอดรหัสวัตถุที่มีอาร์เรย์จะล้มเหลว
สิ่งที่ฉันทำง่ายมาก:
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
}
}
โบนัส: ซ่อนการนำไปใช้> ทำให้เป็นชุดสะสม
การซ่อนรายละเอียดการใช้งานเป็นความคิดที่ดีเสมอ สำหรับสิ่งนี้คุณต้องใช้รหัสเพิ่มอีกนิด เคล็ดลับคือเพื่อให้สอดคล้องDirectionsList
ไปCollection
และทำให้ภายในlist
อาร์เรย์ส่วนตัว:
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)
}
}
คุณสามารถอ่านเพิ่มเติมเกี่ยวกับการปฏิบัติตามคอลเลกชันที่กำหนดเองในโพสต์บล็อกนี้โดย John Sundell: https://medium.com/@johnsundell/creating-custom-collections-in-swift-a344e25d0bb0