Кодируемый, декодируемый только значение из словаря

У меня есть ответ JSON API. Это также возвращает значение, которое представляет собой словарь. Как я могу добиться, чтобы хранить / отображать только значение этого словаря. Вот пример, который можно просто положить на игровую площадку:

id = ["$oid": "591ae6cb9d1fa2b6e47edc33"]

должно быть только

id = "591ae6cb9d1fa2b6e47edc33"

Вот пример, который можно просто положить на игровую площадку:

import Foundation

struct Location : Decodable {
    enum CodingKeys : String, CodingKey {
        case id = "_id"
    }
    var id : [String:String]? // this should be only a string with the value of "$oid"
}

extension Location {
    public init(from decoder: Decoder) throws {
        let values = try decoder.container(keyedBy: CodingKeys.self)
        id = try values.decode([String:String]?.self, forKey: .id)
    }
}


var json = """
[
    {
        "_id": {
            "$oid": "591ae6cb9d1fa2b6e47edc33"
        }
    },
    {
        "_id": {
            "$oid": "591ae6cd9d1fa2b6e47edc34"
        }
    }
]

""".replacingOccurrences(of: "}\n{", with: "}\\n{").data(using: .utf8)!

let decoder = JSONDecoder()

do {
    let locations = try decoder.decode([Location].self, from: json)
    locations.forEach { print($0) }
} catch {
    print(error.localizedDescription )
}

1 ответ

Решение

Вы были почти там

struct Location {
    var id: String
}

extension Location: Decodable {
    private enum CodingKeys: String, CodingKey {
        case id = "_id"
    }

    public init(from decoder: Decoder) throws {
        let values = try decoder.container(keyedBy: CodingKeys.self)
        let _id = try values.decode([String: String].self, forKey: .id)
        id = _id["$oid"]!
    }
}

Если у вас есть ключи под _id в данных JSON я настоятельно рекомендую вам создать частную структуру, которая представляет структуру в интересах безопасности типов.

Другие вопросы по тегам