I am receiving and trying to parse a json file that contains event data. It is a dictionary of dictionaries organized like so with a random event id # as the key to each:
{
"19374176-122" :
{
"event_title" : "Cool Fun Thing to Do",
"description" : "Have fun and do something cool",
"time_start" : "13:00:00",
"time_end" : "14:00:00"
},
"9048-5761634" :
{
"event_title" : "Nap Time",
"description" : "Lay down and go to sleep.",
"time_start" : "15:00:00",
"time_end" : "16:00:00"
}
}
I have created a structure for the event
struct Event: Codable{
let event_title: String
let description: String
let time_start: String
let time_end: String
}
And tried to decode
do{
let eventData = try JSONDecoder().decode([Event].self, from: data)
DispatchQueue.main.async {
print(eventData)
//self.events = eventData
self.collectionView?.reloadData()
}
} catch let jsonError{
print(jsonError)
}
But I get the error that I'm trying to decode an array but getting a dictionary
typeMismatch(Swift.Array<Any>, Swift.DecodingError.Context(codingPath: [], debugDescription: "Expected to decode Array<Any> but found a dictionary instead.", underlyingError: nil))
So then I tried to create a structure for the Root of the json file
struct Root: Codable {
let event_number: Event
}
And decode that
do{
let eventData = try JSONDecoder().decode(Root.Event.self, from: data)
DispatchQueue.main.async {
print(eventData)
//self.events = eventData
self.collectionView?.reloadData()
}
} catch let jsonError{
print(jsonError)
}
But since the key for this dictionary of dictionaries is not actually "event_number" I can't get that data
keyNotFound(CodingKeys(stringValue: "event_number", intValue: nil), Swift.DecodingError.Context(codingPath: [], debugDescription: "No value associated with key CodingKeys(stringValue: \"event_number\", intValue: nil) (\"event_number\").", underlyingError: nil))
What am I missing here? I feel like this should be relatively simple, I must just be completely overlooking something.
You need
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
let eventData = try decoder.decode([String:Event].self, from: data)
struct Event: Codable {
let eventTitle, description, timeStart, timeEnd: String
}
{}
means a dictionary and []
means an array