Swift Codable: вложенный словарь не читается - PullRequest
0 голосов
/ 17 октября 2018

Я получаю некоторые JSON, как это (это псевдо, не все ключи здесь):

{
    "absolute_magnitude_h" = "23.4";
    ...
    "close_approach_data" = (
                {
            "close_approach_date" = "1994-09-03";
            "epoch_date_close_approach" = 778575600000;
            "orbiting_body" = Earth;
}

У меня есть объект с этой структурой:

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]()

    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"
    }

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

struct NEOCloseApproachData:Codable {

    var closeApproachDate:Date
    var epochDateCloseApproach:Date
    var orbitingBody:String

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

и вмой файл У меня есть этот код:

if let arrNEOs = dictJSON["near_earth_objects"] as? Array<Any> {

    for thisNEODict in arrNEOs {

     do {
         let jsonData = try JSONSerialization.data(withJSONObject: thisNEODict, options: .prettyPrinted)
         let thisNEOObj = try? JSONDecoder().decode(NEOObj.self, from: jsonData)
         print(thisNEOObj!.closeApproachData)
     } catch {

     }
    }

   }

Но closeApproachData никогда не заполняется.Что я делаю не так?

Ответы [ 2 ]

0 голосов
/ 17 октября 2018

Причиной, по которой после декодирования вы получаете пустое свойство closeApproachData, является отсутствие соответствующего ключа для этого свойства в вашем перечислении CodingKeys .

Что касается документа Apple, он сообщает следующее:

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

Это означает, что сгенерированная реализация метода decode для вашего класса NEOObj исключает реализацию декодирования для свойства closeApproachData.

Вот ссылка наДокументация Apple о кодировании и декодировании пользовательских типов .Более подробную информацию можно найти в разделе «Выбор свойств для кодирования и декодирования с использованием ключей кодирования».

Кроме того, ваш пользовательский класс NEOCloseApproachData должен соответствовать протоколу кодирования.

0 голосов
/ 17 октября 2018

Есть несколько вещей, которые необходимо изменить, чтобы он работал.


closeApproachData должно быть типа [NEOCloseApproachData].Вы не включили CloseApproachCodingKeys в свой код, но, вероятно, это неправильно.


NEOObj.CodingKeys должен иметь регистр для closeApproachData, который будет выглядеть как

case closeApproachData = "close_approach_data"

NEOCloseApproachData необходим специальный декодер для работы с датами closeApproachDate и epochDateCloseApproach.Поскольку JSON имеет разные форматы для каждого (String и Int соответственно), вы не можете использовать JSONDecoder.dateDecodingStrategy, поскольку он будет применяться ко всем датам.

...