Reputation: 133
I have some simple JSON data that I'm trying to decode, but it keeps failing. Here is the JSON. It's supposed to be an array, but at the moment it only has 1 thing in it.
[
{
"good" : "You're great",
"terrible" : "You're terrible"
}
]
Here is the model that I have in Xcode.
struct Affirmation: Identifiable, Codable {
var id: UUID = UUID()
var good: String
var terrible: String
}
Here is how the data is loaded.
class AffirmationData: ObservableObject {
@Published var affirmations = [Affirmation]()
init() {
//Load data on initialization
load()
}
func load() {
//Get URL
guard let url = Bundle.main.url(forResource: "Affirmations", withExtension: "json")
else {
print("Affirmations file not found")
return
}
//Get data
let data = try? Data(contentsOf: url)
do {
//Try to decode
let affirmations = try JSONDecoder().decode([Affirmation].self, from: data!)
//Set affirmations
self.affirmations = affirmations
} catch {
//Display error if there is one
print("Affirmations could not be decoded. Error below.")
print (error)
}
/*//Decode data
guard let affirmations = try? JSONDecoder().decode([Affirmation].self, from: data!)
else {
print("Affirmations could not be decoded")
return
}*/
}
}
Finally, here is the error I'm getting
Affirmations could not be decoded. Error below.
dataCorrupted(Swift.DecodingError.Context(codingPath: [], debugDescription: "The given data was not valid JSON.", underlyingError: Optional(Error Domain=NSCocoaErrorDomain Code=3840 "Invalid value around line 1, column 0." UserInfo={NSDebugDescription=Invalid value around line 1, column 0., NSJSONSerializationErrorIndex=0})))
What can I do to resolve this? Also, is it related to how the ID is not in the JSON itself? I was thinking it was that, but I much prefer the ID to be set this way instead if possible. Thanks!
EDIT: I changed it so the ID is in the JSON data as you can see below. It doesn't seem to make a difference. It's the same error.
[
{
"id" : 1,
"good" : "You're great",
"terrible" : "You're terrible"
}
]
struct Affirmation: Identifiable, Codable {
var id: Int
var good: String
var terrible: String
}
Upvotes: 0
Views: 4056
Reputation: 285039
You are going to decode a key which is not part of the JSON.
There are two options:
Add CodingKeys
and omit the key id
private enum CodingKeys: String, CodingKey { case good, terrible }
Declare the member in the struct as constant, in this case the compiler skips all members with a default value
let id = UUID()
however you get a warning:
immutable property will not be decoded because it is declared with an initial value which cannot be overwritten
Your last example with id : Int
does work.
Basically you should declare all decoded struct members as constants which are immutable.
Upvotes: 1