I am getting the typeMismatch error when decoding JSON. Error states that it expects a Dictionary but found an array

The full error is typeMismatch(Swift.Dictionary<Swift.String, Any>, Swift.DecodingError.Context(codingPath: [], debugDescription: "Expected to decode Dictionary<String, Any> but found an array instead.", underlyingError: nil))


I have tried both [QuoteData].self and QuoteData.self


Code Block
func parseJSON(quoteData: Data) {
let decoder = JSONDecoder()
do {
let decodedData = try decoder.decode(QuoteData.self, from: quoteData)
//print(decodedData.zero[0].content)
print(decodedData.zero[0].content)
} catch {
print(error)
}
}

Here is my struct

Code Block
struct QuoteData: Decodable, Equatable {
private enum CodingKeys : String , CodingKey { case zero = "0" }
let zero : [Zero]
struct Zero: Decodable, Equatable {
let content : String
}
}

This is the JSON I am requesting
Code Block
[1 item
0: {
"content":"If you are out to describe the truth, leave elegance to the tailor."
"author":"Albert Einstein"
"category":"truth"
}
]

Code Block

Answered by OOPer in 652192022

This is what I got when I added that line. 

Thanks. Text would always be better than image when showing JSON data.

With removing escaping characters and re-formatted, your JSON looks like this:
Code Block
[
{
"content":"That's a great feeling to know that I'm going into a project that I have no idea what will become of that movie, but I really trust Ang Lee. And I really trusted Ron. It's just really nice to work with people that you feel that way about.",
"url":"https://URL.. Connelly",
"category":"trust"
}
]


No 1 item, No 0:.

And what is the most important is that the outermost structure is JSON array indicated by [ and ].
You may need to pass an Array type to JSONDecoder.decode.

Something like this:
Code Block
struct QuoteItem: Decodable, Equatable {
let content: String
//let url: URL
//let category: String
}
func parseJSON(quoteData: Data) {
//print(String(data: quoteData, encoding: .utf8) ?? "*")
let decoder = JSONDecoder()
do {
let decodedData = try decoder.decode([QuoteItem].self, from: quoteData) //<- Pass an Array type
//Here, `decodedData` is of type `[QuoteItem]`
print(decodedData[0].content)
} catch {
print(error)
}
}


This is the JSON I am requesting

The data you have shown is not a JSON. Any JSON parser in the world cannot read it.

How have you got it?
In a local file of your project? Or is it some sort of debugging output?
Is it written in a spec of some API you are using?

The first thing you may need to do is clarifying the right data format.


Can you put this line before line 2 of parseJSON and tell us what you get?
Code Block
    print(String(data: quoteData, encoding: .utf8) ?? "*")


I didn't have a way to attach an image. This is what I got when I added that line.

Code Block
Optional("[{\"content\":\"That\'s a great feeling to know that I\'m going into a project that I have no idea what will become of that movie, but I really trust Ang Lee. And I really trusted Ron. It\'s just really nice to work with people that you feel that way about.\",\"url\":\"https://URL.. Connelly\",\"category\":\"trust\"}]"

Accepted Answer

This is what I got when I added that line. 

Thanks. Text would always be better than image when showing JSON data.

With removing escaping characters and re-formatted, your JSON looks like this:
Code Block
[
{
"content":"That's a great feeling to know that I'm going into a project that I have no idea what will become of that movie, but I really trust Ang Lee. And I really trusted Ron. It's just really nice to work with people that you feel that way about.",
"url":"https://URL.. Connelly",
"category":"trust"
}
]


No 1 item, No 0:.

And what is the most important is that the outermost structure is JSON array indicated by [ and ].
You may need to pass an Array type to JSONDecoder.decode.

Something like this:
Code Block
struct QuoteItem: Decodable, Equatable {
let content: String
//let url: URL
//let category: String
}
func parseJSON(quoteData: Data) {
//print(String(data: quoteData, encoding: .utf8) ?? "*")
let decoder = JSONDecoder()
do {
let decodedData = try decoder.decode([QuoteItem].self, from: quoteData) //<- Pass an Array type
//Here, `decodedData` is of type `[QuoteItem]`
print(decodedData[0].content)
} catch {
print(error)
}
}


Thanks that worked. Plus, that gave me some insight on how to view JSON data before i decode it.
I am getting the typeMismatch error when decoding JSON. Error states that it expects a Dictionary but found an array
 
 
Q