I have JSON structure as:
"periods": {
"2018-06-07": [
{
"firstName": "Test1",
"lastName": "Test1"
}
],
"2018-06-06": [
{
"firstName": "Test1",
"lastName": "Test1"
}
]
}
I tried to parse it like this:
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")
}
}
But I can get result for only one value (2018-06-06)
. I have multiple dates here that I want to parse. Is this possible?
Assuming you left out the {
and }
that would surround this block and are required for this to be valid JSON, the following is the simplest solution to getting things parsed, you really don't need to deal with CodingKey
at all since your names match the keys in the JSON, so the synthesized CodingKey
will work just fine:
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)
The key is that the outer JSON is a JSON Object (dictionary/map) with a single key periods
The value of that key is another map of arrays. Just break it down like that and everything falls out pretty much automatically.
Ok, so I figured it out like this:
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
}
}
}
As result I got dictionary like this: ["2018-06-06": [Inner]]
where key is this Date String, and value Inner.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With