Как декодировать вложенную структуру JSON с динамической переменной из вызова API - PullRequest
0 голосов
/ 10 декабря 2018

При вызове этого конкретного API одна из переменных изменяется в зависимости от результатов.

Пример:

{
    "map": {
        "1945206": {
            "installBaseNUMB": 0,
            "serialNumber": "KB1",
            ...
        }
    }
}

1945206 изменится на другой номер, и я не знаю, какчтобы правильно декодировать это.

Моя структура Codable выглядит следующим образом:

struct Map: Codable {
    let the1945206: The1945206?

    enum CodingKeys: String, CodingKey {
        case the1945206 = "1945206"
    }
}

struct The1945206: Codable {
    let installBaseNUMB: Int?
    let serialNumber, woStatus: String?
    let workOrderNumber: Int?
    let woNotes: [String]?
    let woParts: [WoPart]?
}

Если значение 1945206 изменится на другое значение, оно сломается и не даст никаких результатов.Как использовать динамическую переменную при декодировании данных?

Ответы [ 2 ]

0 голосов
/ 10 декабря 2018

Я предложу установить имена, отличные от The1945206, так как они менее читабельны.Я буду использовать MapElement вместо этого.Если вы знаете, что на карте будет только один элемент, и вы не хотите проверять, какой ключ связан с этим значением, вы можете использовать вычисленное свойство var value:MapElement?, чтобы получить его.Возвращает необязательный, потому что словарь let map:[String:MapElement] может быть пустым.

let json = """
{
    "map": {
        "1945206": {
            "installBaseNUMB": 0,
            "serialNumber": "KB1"
        }
    }
}
""".data(using: .utf8)!

struct Container: Codable {
    let map:[String:MapElement]

    var value:MapElement? {
        return map.values.first
    }
}

struct MapElement: Codable {
    let installBaseNUMB: Int
    let serialNumber: String
}

let res = try? JSONDecoder().decode(Container.self,from:json)
print(res?.value as Any)

Обновление:

Если вы хотите использовать несколько MapElement, вы можете изменить var value:MapElement на var values:[MapElement] следующим образом:

struct Container: Codable {
    let map:[String:MapElement]

    var values:[MapElement] {
        return map.values
    }
}

Но имейте в виду, что вы храните данные в виде словаря, поэтому порядок элементов не гарантируется.

0 голосов
/ 10 декабря 2018

Можно попробовать

struct Root : Codable {
   let map: [String:The1945206]
}

let res = try? JSONDecoder().decode(Root.self,from:data)
print(res?.map.values)

{
    "map": {
        "1945204": {
            "installBaseNUMB": 0,
            "serialNumber": "KB1",
            ...
        },
        "1945205": {
            "installBaseNUMB": 0,
            "serialNumber": "KB1",
            ...
        },
        "1945206": {
            "installBaseNUMB": 0,
            "serialNumber": "KB1",
            ...
        }
    }
}
...