несколько значений JSON CodingKeys при выпуске - PullRequest
0 голосов
/ 24 июня 2018

Давайте предположим, что у нас есть структура JSON:

    {
    "July": [
        {
        ...
            "startDate": "July 10",
            "endDate": "July 11",
        ...
        },
        {
            ...
        },
        {
            ...
        },
        {
            ...
        }
    ]
}

Я пытаюсь проанализировать этот API со следующей структурой, используя только собственный swift.

struct Listing: Codable {
    let months: [Month]


    enum CodingKeys: String, CodingKey {
        case months = "June" //here we need all months for the whole year.
    }

}

struct Month: Codable {
    ...
    let startDate: String
    let endDate: String
    ...

    enum CodingKeys: String, CodingKey {
        ...
    }
}

Проблемаявляется то, что API будет возвращать на запрос каждый раз новый ответ JSON с новым месяцем, таким образом, мне нужно несколько случаев «CodingKeys»: «июль», «август» и т. д., в то же время структура месяца может использоваться повторно.Была идея решить проблему сопоставления сущности, хотя я думаю, что может быть более элегантное решение.Пожалуйста, дайте мне знать, если у вас есть идеи, как упростить решение.

1 Ответ

0 голосов
/ 24 июня 2018

Прежде всего, если вы собираетесь только декодировать, JSON принимает только Decodable.

Рекомендую расшифровать months как словарь [String:[Month]]

struct Listing: Decodable {
    let months: [String:[Month]]
}

Затем получите массив Month только по известному ключу месяца.

Или используйте enum

enum MonthName : String, Decodable  {
    private enum CodingKeys : String, CodingKey { case january = "January", february = "February", ... december = "December" }
    case January, February, ... December
}

struct Listing: Decodable {
    let months: [MonthName:[Month]]
}

Edit:

Вы также можете написать собственный инициализатор для извлечения массива Month, он предполагает, что в корневом объекте есть только один словарь с одной парой ключ-значение.

struct Listing: Decodable {

    let months: [Month]

    init(from decoder: Decoder) throws {
        let container = try decoder.singleValueContainer()
        let monthData = try container.decode([String:[Month]].self)
        months = monthData[monthData.keys.first!]!
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...