简体   繁体   English

JSON 返回相似结构的 2 个链接的解码错误

[英]JSON Decoding Error for 2 Links Returning Similar Structures

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).我有以下可用的代码here解码来自Kitsu API的JSON响应(真的只是在操场环境中复制和粘贴,你应该很高兴)。

I am running into some decoding error that makes the code in the try statement fail and I have no idea why.我遇到了一些解码错误,导致try语句中的代码失败,我不知道为什么。

I have two links that return the same JSON body (different results but same structure) except one fails and one doesn't.我有两个链接返回相同的 JSON 主体(不同的结果但相同的结构),除了一个失败而一个没有。

// "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:为了帮助调试失败的那个,我使用以下语句打印出data

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):有了这个,我可以看到数据 object 包含我需要的一切,所以我排除了错误的响应(文本太大而无法复制,所以这是一个截图,你会得到图片):

在此处输入图像描述

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.我已经并排比较了 json,就像我说的,响应之间的结构是相同的,只是内容不同。

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:所以,不要隐藏错误,就像你对print("error, wtf")所做的那样,而是记录/打印它:

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))错误将是: 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, ie bottom up.我发现向后阅读错误更容易,即自下而上。

Right away, you see that the issue is "found null value instead" - ie your model didn't have an optional for something that was null.马上,您会看到问题是“找到了 null 值” - 即您的 model 没有 null 的选项。

Where?在哪里? CodingKeys(stringValue: "coverImage", intValue: nil)] - so, coverImage is null. CodingKeys(stringValue: "coverImage", intValue: nil)] - 所以, coverImage是 null。

Where is that?哪里是? CodingKeys(stringValue: "attributes", intValue: nil) - under attributes , which you probably knew. CodingKeys(stringValue: "attributes", intValue: nil) - 在attributes下,你可能知道。

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 , ie data[4] , which is the fifth element. [CodingKeys(stringValue: "data", intValue: nil), _JSONKey(stringValue: "Index 4", intValue: 4) - data索引4的元素,即data[4] ,为第五个元素。

Long story short, at least one (but actually two) of the Anime objects' attribute property has coverImage: null in the "broken" response.长话短说,至少有一个(但实际上是两个) Anime对象的attribute在“损坏”响应中具有coverImage: null To solve, make this property optional:要解决此问题,请将此属性设为可选:

class Attributes: Codable {
   // other properties
   let coverImage: CoverImage?
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM