0

I have the following piece of code available here that decodes a JSON response from the Kitsu API (seriously just copy and paste in a playground environment and you should be good to go).

I am running into some decoding error that makes the code in the try statement fail and I have no idea why.

I have two links that return the same JSON body (different results but same structure) except one fails and one doesn't.

// "https://kitsu.io/api/edge/anime?sort=popularityRank" <-- works
// "https://kitsu.io/api/edge/anime?sort=-startDate" <-- does not work

To help debug the one that fails I print out data with the following statement:

print(String(data: data!, encoding: String.Encoding.utf8) as Any) // "as Any" to suppress warnings

And with this I am able to see the data object contains everything I need, so I'm ruling out a bad response (text was too large to copy so here's a screenshot, you'll get the picture):

enter image description here

If I had to guess, the issue is in the parsing, but the way I'm parsing it works for the first link. What exactly can I do to debug this? I've compared the json side by side and like I said, the structure between the responses is the same, only the content differs.

1 Answer 1

1

If you read the error closely, you'd find that it's quite descriptive. So, don't hide the error, like you did with print("error, wtf"), and instead log/print it:

do {
   let animeData = try JSONDecoder().decode(AnimeData.self, from: data!)
} catch {
   print(error)
}

And the error would be: valueNotFound(Swift.KeyedDecodingContainer<__lldb_expr_163.CoverImage.CodingKeys>, Swift.DecodingError.Context(codingPath: [CodingKeys(stringValue: "data", intValue: nil), _JSONKey(stringValue: "Index 4", intValue: 4), CodingKeys(stringValue: "attributes", intValue: nil), CodingKeys(stringValue: "coverImage", intValue: nil)], debugDescription: "Cannot get keyed decoding container -- found null value instead.", underlyingError: nil))

I find it easier to read the error backwards, i.e. bottom up.

Right away, you see that the issue is "found null value instead" - i.e. your model didn't have an optional for something that was null.

Where? CodingKeys(stringValue: "coverImage", intValue: nil)] - so, coverImage is null.

Where is that? CodingKeys(stringValue: "attributes", intValue: nil) - under attributes, which you probably knew.

But which one, since it's a property of an array element? [CodingKeys(stringValue: "data", intValue: nil), _JSONKey(stringValue: "Index 4", intValue: 4) - an element of data index 4, i.e. data[4], which is the fifth element.

Long story short, at least one (but actually two) of the Anime objects' attribute property has coverImage: null in the "broken" response. To solve, make this property optional:

class Attributes: Codable {
   // other properties
   let coverImage: CoverImage?
}
Sign up to request clarification or add additional context in comments.

1 Comment

Marking this as the correct answer for two reasons: 1. @New Dev helped me find that the issue turned out to be one of the attributes being 'nil' in the json, which my class did not account for. 2. Pointing out that I was hiding the error, which of course is why I couldn't find the information I needed

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.