Swift Codable с динамическими клавишами - PullRequest
0 голосов
/ 06 июня 2018

У меня есть структура JSON как:

"periods": {
    "2018-06-07": [
      {
        "firstName": "Test1",
        "lastName": "Test1"
      }
    ],
    "2018-06-06": [
      {
        "firstName": "Test1",
        "lastName": "Test1"
      }
    ]
}

Я попытался разобрать это так:

public struct Schedule: Codable {
    public let periods: Periods
}

public struct Periods: Codable {
    public let unknown: [Inner]

    public struct Inner: Codable {
        public let firstName: String
        public let lastName: String
    }

    private struct CustomCodingKeys: CodingKey {
        var stringValue: String
        init?(stringValue: String) {
            self.stringValue = stringValue
        }

        var intValue: Int?
        init?(intValue: Int) {
            return nil
        }
    }

    public init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CustomCodingKeys.self)
        self.unknown = try container.decode([Inner].self, forKey: CustomCodingKeys(stringValue: "2018-06-06")
    }
}

Но я могу получить результат только для одного значения(2018-06-06).У меня есть несколько дат здесь, которые я хочу разобрать.Это возможно?

Ответы [ 2 ]

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

Предполагая, что вы пропустили { и }, которые будут окружать этот блок и необходимы для того, чтобы этот код был действительным JSON, ниже приведено простейшее решение для анализа объектов, вам действительно не нужно иметь дело сCodingKey вообще, поскольку ваши имена соответствуют ключам в JSON, поэтому синтезированный CodingKey будет работать просто отлично:

public struct Schedule: Codable {
    public let periods : [String:[Inner]]
}

public struct Inner: Codable {
    public let firstName: String
    public let lastName: String
}

let schedule = try? JSONDecoder().decode(Schedule.self, from: json)

print(schedule?.periods.keys)

print(schedule?.periods["2018-06-07"]?[0].lastName)

Ключ в том, что внешний JSON является объектом JSON (словарь / карта) с одним ключом periods Значением этого ключа является другая карта массивов.Просто разбейте его так, и все автоматически выпадет.

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

Хорошо, я понял это следующим образом:

public struct Schedule: Codable {
    public let periods: Periods
}

public struct Periods: Codable {
    public var innerArray: [String: [Inner]]

public struct Inner: Codable {
    public let firstName: String
    public let lastName: String
}

private struct CustomCodingKeys: CodingKey {
    var stringValue: String
    init?(stringValue: String) {
        self.stringValue = stringValue
    }
    var intValue: Int?
    init?(intValue: Int) {
        return nil
    }
}
public init(from decoder: Decoder) throws {
    let container = try decoder.container(keyedBy: CustomCodingKeys.self)

    self.innerArray = [String: [Inner]]()
    for key in container.allKeys {
        let value = try container.decode([Inner].self, forKey: CustomCodingKeys(stringValue: key.stringValue)!)
        self.innerArray[key.stringValue] = value
    }
}

В результате я получил словарь, подобный следующему: ["2018-06-06": [Inner]] где ключ это строка даты,и значение Inner.

...