Сбой Swift Codable во вложенном словаре

У меня есть сложный объект JSON, который выглядит примерно так (он усечен, чтобы просто дать представление о вложенности:

{
    "absolute_magnitude_h" = "23.4";
    ...
    "close_approach_data" = (
                {
            "close_approach_date" = "1994-09-03";
            "epoch_date_close_approach" = 778575600000;
            "orbiting_body" = Earth;
    })
    "orbital_data" =     {
        "aphelion_distance" = "4.058036874987604";
       "orbit_class" = { 
            "orbit_class_type" = APO;
        }
    }

}

Мой кодируемый объект выглядит так:

struct NEOObj:Codable {

    var absoluteMagnitudeH:Float
    var designation:String
    var isPotentiallyHazardousAsteroid:Bool
    var isSentryObject:Bool
    var name:String
    var nasaJPLURL:String
    var neoReferenceID:String
    var closeApproachData:[NEOCloseApproachData] = [NEOCloseApproachData]()
    var orbitalData:NEOOrbitalData?

    private enum CodingKeys: String, CodingKey {
        case absoluteMagnitudeH = "absolute_magnitude_h"
        case designation = "designation"
        case isPotentiallyHazardousAsteroid = "is_potentially_hazardous_asteroid"
        case isSentryObject = "is_sentry_object"
        case name = "name"
        case nasaJPLURL = "nasa_jpl_url"
        case neoReferenceID = "neo_reference_id"
        case closeApproachData = "close_approach_data"
        case orbitalData = "orbital_data"
    }

}

struct NEOCloseApproachData:Codable {

    var closeApproachDate:String
    var orbitingBody:String
    var epochDateCloseApproach:Int

    enum CodingKeys: String, CodingKey {
        case orbitingBody = "orbiting_body"
        case closeApproachDate = "close_approach_date"
        case epochDateCloseApproach = "epoch_date_close_approach"
    }
}

struct NEOOrbitalData: Codable {

    var aphelionDistance:Float

    enum CodingKeys: String, CodingKey {
        case aphelionDistance = "aphelion_distance"
    }

}

и мой код:

do {

    let thisNEOObj = try? JSONDecoder().decode(NEOObj.self, from: jsonData)
    print(thisNEOObj)
   } catch {

   }

Я могу без проблем получить ключи / значения верхнего уровня (absolute_magnitude_h), например, и closeApproachData также заполняется. Но если я попытаюсь получить orbital_data, thisNEOObj станет равным нулю. Я еще даже не пытался получить orbit_class. : (

Где я ошибаюсь?


person PruitIgoe    schedule 17.10.2018    source источник
comment
поэтому вы должны поместить print (error) в блок catch, попробовать и прикрепить ошибку   -  person Sh_Khan    schedule 18.10.2018
comment
Согласен с @Sh_Khan. Также я предлагаю вам использовать необязательные значения.   -  person Ahmet Sina    schedule 18.10.2018
comment
Ошибки нет, это просто нулевой объект, когда я пытаюсь получить orbital_data, если я прокомментирую это, он работает.   -  person PruitIgoe    schedule 18.10.2018
comment
@PruitIgoe, вы можете попробовать изменить свой NEOOrbitalData. aphelionDistance на Double   -  person Quoc Nguyen    schedule 18.10.2018
comment
AphelionDistance кажется строкой. В любом случае, попробуйте декодировать все orbital_data, добавив orbital_class. Вы также можете попробовать добавить инициализацию с кодером и декодером, чтобы вы могли кодировать и декодировать как хотите, и подробно проверять, что не так.   -  person Andrew21111    schedule 18.10.2018
comment
Пожалуйста, научитесь читать JSON. Все очень просто. Например, все в двойных кавычках - это String, даже "1.2" и "false". Нет никаких исключений.   -  person vadian    schedule 18.10.2018


Ответы (2)


"4.058036874987604" является String и не может быть декодирован в var aphelionDistance: Float без специального декодирования.

person Fabian    schedule 18.10.2018

Я бы порекомендовал вам взглянуть на статью об использовании вашего Буханка, которая охватывает вложенные структуры и обрабатывает настраиваемые преобразования. Скорее всего, вам потребуется создать собственный декодер для обработки различных видов преобразования данных (хотя большинство из них будут шаблонными). Вы также можете пропустить статью и просмотреть код в сущности. Я считаю, что ваши структуры должны включать в себя все ключи JSON в данных. Вы также можете столкнуться с проблемой, потому что Float - это «Тип значения с плавающей запятой одинарной точности», а Double - «Тип значения с плавающей запятой двойной точности». Хотя я дважды не проверял, вызовут ли предоставленные данные проблемы на вашем устройстве, но, вероятно, проще переключиться на 64-битный тип Double.

person Tommie C.    schedule 13.01.2019