Reputation: 1301
I'm making a small app to practice parsing JSON into a tableview, and I'm using the Ticketmaster API. This is the JSON, and these are the structs that I have set up:
struct Welcome: Decodable {
let embedded: WelcomeEmbedded
enum CodingKeys: String, CodingKey{
case embedded = "_embedded"
}
}
struct WelcomeEmbedded: Decodable {
let events: [Event]
}
struct Event: Decodable {
let name: String
let dates: Dates
let eventUrl: String?
let embedded: EventEmbedded
enum CodingKeys: String, CodingKey {
case name
case dates
case eventUrl
case embedded = "_embedded"
}
}
struct EventEmbedded: Decodable {
let venue: Venue
}
struct Dates: Decodable {
let start, end: End
}
struct Venue: Decodable {
let name: String
}
Before adding in the value let embedded: EventEmbedded
to the Event
struct, things worked fine, but after adding in that line, when running the app I get an error:
Error decoding JSON: typeMismatch(Swift.Dictionary<Swift.String, Any>, Swift.DecodingError.Context(codingPath: [CodingKeys(stringValue: "_embedded", intValue: nil), CodingKeys(stringValue: "events", intValue: nil), _JSONKey(stringValue: "Index 0", intValue: 0), CodingKeys(stringValue: "_embedded", intValue: nil), CodingKeys(stringValue: "venue", intValue: nil)], debugDescription: "Expected to decode Dictionary<String, Any> but found an array instead.", underlyingError: nil))
I'm wondering how adding that line alone results in an error, is it anything to do with the fact that I have a value named embedded
in two structs (Welcome
and Event
), and both use the coding key _embedded
?
For some added detail, to parse the JSON I have a variable var eventData = [Event]()
and call this function in viewDidLoad
to populate eventData
with the necessary data:
fetchData(url: apiUrl) { (result: FetchResult<Welcome>) -> (Void) in
switch result {
case .success(let object): self.eventData = object.embedded.events
case .failure(let error): print("\nError decoding JSON: \(error)\n\n")
}
DispatchQueue.main.async {
self.tableView.reloadData()
}
}
The error also says CodingKeys(stringValue: "venue", intValue: nil)], debugDescription: "Expected to decode Dictionary<String, Any> but found an array instead.
. But looking at the JSON, the data under venue
is structured the same way as the rest of the values, and they don't give me an error.
What can I do differently here to get back on track?
Upvotes: 0
Views: 308
Reputation: 285074
Please learn to read Codable
errors. They are very, very, very descriptive.
Error decoding JSON: typeMismatch(Swift.Dictionary, Swift.DecodingError.Context(codingPath: [CodingKeys(stringValue: "_embedded", intValue: nil), CodingKeys(stringValue: "events", intValue: nil), _JSONKey(stringValue: "Index 0", intValue: 0), CodingKeys(stringValue: "_embedded", intValue: nil), CodingKeys(stringValue: "venue", intValue: nil)], debugDescription: "Expected to decode Dictionary but found an array instead.", underlyingError: nil))
typeMismatch
is the error typeCodingKeys(stringValue: "_embedded", CodingKeys(stringValue: "events"), CodingKeys(stringValue: "_embedded"), CodingKeys(stringValue: "venue")
is the key path (_embedded/events/_embedded/venue
)Expected to decode Dictionary<String, Any> but found an array instead
is the error message.
Expected
is the wrong type you proposed.found
is the actual type.
A dictionary
is the struct, an array
is an array of the struct.
Change EventEmbedded
to
struct EventEmbedded: Decodable {
let venue: [Venue]
}
Upvotes: 2