Swift의 [String: Any]를 디코딩하는 방법은 무엇입니까?

2706 단어 codablejsonswift
JSON을 [String: Any]로 디코딩해야 합니까? 다음은 이 작업을 수행하는 방법입니다.

요구 사항



대답은 Any 유형을 사용하여 이 작업을 수행할 수 없다는 것입니다. Any 보다 구체적인 것을 지정해야 합니다.

Dictionary is automatically decodable if its elements are decodable. Type Any is not decodable.



그러나 대답을 찾고 있다면 실제로 어떻게 든 처리해야 하는 일종의 JSON이 있음을 의미합니다. 주제는 [Any] 와 같은 배열과도 관련이 있습니다.

해결책


Any 유형의 가능한 값의 유한 수를 지정해야 합니다. 예를 들어 다음과 같은 두 가지 다른 구조가 있을 것으로 예상합니다.

struct Payload: Codable {
    let id: String
    let eventName: String
    let metadata: [Metadata]
}

struct Metadata: Codable {
    let name: String?
    let price: Double?
    let rating: Int?
}

하지만 물론 당신은 할 수 없습니다

let decodedData = try JSONDecoder().decode([String: Any].self, from: json.data(using: .utf8)!)

사용된 유형Any이 있기 때문입니다.

우선 이 사전의 JSON이 어떻게 생겼는지 알아야 합니다. 다음과 같이 될 것입니다.

{
    "keyNumber1": {
        "type": "payload",
        "data": {
            "id": "someId1",
            "eventName": "Event Name 1",
            "metadata": []
        }
    },
    "keyNumber2": {
        "type": "metadata",
        "data": {
            "name": "Metadata Name",
            "price": 123.4,
            "rating": 100
        }
    }
}

그런 다음 다음과 같이 enum 유형 대신 Any를 정의해야 하기 때문에 간단합니다.

enum DataType: String, Codable {
    case payload
    case metadata
}

enum MyValue: Decodable {
    case payload(_ payload: Payload)
    case metadata(_ metadata: Metadata)

    private enum CodingKeys: String, CodingKey {
        case `type`
        case `data`
    }

    init(from decoder: Decoder) throws {
        let map = try decoder.container(keyedBy: CodingKeys.self)
        let dataType = try map.decode(DataType.self, forKey: .type)
        switch dataType {
        case .payload:
            self = .payload(try map.decode(Payload.self, forKey: .data))
        case .metadata:
            self = .metadata(try map.decode(Metadata.self, forKey: .data))
        }
    }
}

다음 코드를 사용하여 JSON을 디코딩합니다.

let decodedData = try JSONDecoder().decode([String: MyValue].self, from: json.data(using: .utf8)!)

전체 플레이그라운드 코드:


좋은 웹페이지 즐겨찾기