실제로 위의 답변은 정말 훌륭하지만 지속적으로 개발되는 클라이언트 / 서버 프로젝트에서 많은 사람들이 필요로하는 세부 사항이 누락되었습니다. 우리는 백엔드가 시간이 지남에 따라 지속적으로 진화하는 동안 앱을 개발합니다. 이는 일부 열거 형 사례가 그 진화를 바꿀 것임을 의미합니다. 따라서 알려지지 않은 경우를 포함하는 열거 형 배열을 디코딩 할 수있는 열거 형 디코딩 전략이 필요합니다. 그렇지 않으면 배열이 포함 된 객체의 디코딩이 실패합니다.
내가 한 일은 매우 간단합니다.
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) 에서 사용자 지정 컬렉션 준수에 대한 자세한 내용을 확인할 수 있습니다.