Swift Decodable-제네릭 유형을 피하는 방법?
Aug 19 2020
JSON REST API에서 복잡한 중첩 객체를 검색하고 있습니다.
DocumentDraft
- uuid: String
- schema: Schema // Very complicated object with many variations
- url: String
- values: [Value]
- successors: [String]
- predecessors: [String]
Value
- key: String
- val: String? OR [String]? // <-- This is the problem
이를 처리하는 적절한 방법은 제네릭 유형을 도입하는 것입니다.
struct Value<V: Decodable>: Decodable {
let key: String
let val: V?
}
...하지만 그래도 values
혼합 배열이 될 수 있으므로 무엇을 선언하는 V
것이 도움이 될지 모르겠습니다 .
그러나 물론 제네릭 유형은 계층 구조, DocumentDraft
개체, 게시자, API 호출 등 으로 전파 되어 매우 깨끗하고 읽기 쉬운 호출 및 개체의 전체 체인을 오염시킵니다. 이 문제는 수준에서만 처리 Value
하고 JSONDecoder가 어떻게 든 둘 중 하나를 반환하도록합니다.
옵션의 두 가지 가능성을 다루는 또 다른 방법이 val
아니라 하나 String
또는 [String]
전체 부모 개체를 변경하지 않고는?
답변
4 gcharita Aug 19 2020 at 12:31
[String]
유형 만 사용하고 다음 과 같이 프로토콜 의 init(from:)
기능을 수동으로 구현 하여이를 달성 할 수 있습니다 Decodable
.
struct Value: Decodable {
let key: String
let val: [String]?
enum CodingKeys: String, CodingKey {
case key, val
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
key = try container.decode(String.self, forKey: .key)
do {
if let string = try container.decodeIfPresent(String.self, forKey: .val) {
val = [string]
} else {
val = nil
}
} catch DecodingError.typeMismatch {
val = try container.decodeIfPresent([String].self, forKey: .val)
}
}
}
String
값으로 디코딩이 성공하면 요소가 하나만있는 문자열 배열을 만듭니다. String
값에 대한 디코딩이 실패하면 다음과 같이 디코딩하십시오.[String]