JSON 2 个链接返回相似结构的解码错误
JSON Decoding Error for 2 Links Returning Similar Structures
我有以下代码可用here that decodes a JSON response from the Kitsu API(真的只是在游乐场环境中复制和粘贴,你应该可以开始了)。
我 运行 遇到一些解码错误,导致 try
语句中的代码失败,我不知道为什么。
我有两个 link return 相同的 JSON 主体(不同的结果但相同的结构)除了一个失败而一个没有。
// "https://kitsu.io/api/edge/anime?sort=popularityRank" <-- works
// "https://kitsu.io/api/edge/anime?sort=-startDate" <-- does not work
为了帮助调试失败的那个,我使用以下语句打印出 data
:
print(String(data: data!, encoding: String.Encoding.utf8) as Any) // "as Any" to suppress warnings
有了这个,我能够看到数据对象包含我需要的一切,所以我排除了错误的响应(文本太大而无法复制,所以这是一个屏幕截图,你会得到图片):
如果我不得不猜测,问题出在解析中,但我解析它的方式适用于第一个 link。我究竟能做些什么来调试呢?我已经并排比较了 json,就像我说的,响应之间的结构是相同的,只是内容不同。
如果您仔细阅读错误,您会发现它的描述性很强。所以,不要隐藏错误,就像您对 print("error, wtf")
所做的那样,而是 log/print 它:
do {
let animeData = try JSONDecoder().decode(AnimeData.self, from: data!)
} catch {
print(error)
}
错误是:
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))
我发现向后阅读错误更容易,即自下而上。
马上,您会发现问题是“找到了空值”——即您的模型没有可选的空值。
在哪里? CodingKeys(stringValue: "coverImage", intValue: nil)]
- 所以,coverImage
为空。
那是哪里? CodingKeys(stringValue: "attributes", intValue: nil)
- 在 attributes
下,您可能知道。
但是哪一个,因为它是数组元素的 属性? [CodingKeys(stringValue: "data", intValue: nil), _JSONKey(stringValue: "Index 4", intValue: 4)
- data
索引 4
的一个元素,即 data[4]
,这是第五个元素。
长话短说,至少有一个(但实际上是两个)Anime
对象的 attribute
属性 在“损坏”响应中有 coverImage: null
。要解决此问题,请将此 属性 设为可选:
class Attributes: Codable {
// other properties
let coverImage: CoverImage?
}
我有以下代码可用here that decodes a JSON response from the Kitsu API(真的只是在游乐场环境中复制和粘贴,你应该可以开始了)。
我 运行 遇到一些解码错误,导致 try
语句中的代码失败,我不知道为什么。
我有两个 link return 相同的 JSON 主体(不同的结果但相同的结构)除了一个失败而一个没有。
// "https://kitsu.io/api/edge/anime?sort=popularityRank" <-- works
// "https://kitsu.io/api/edge/anime?sort=-startDate" <-- does not work
为了帮助调试失败的那个,我使用以下语句打印出 data
:
print(String(data: data!, encoding: String.Encoding.utf8) as Any) // "as Any" to suppress warnings
有了这个,我能够看到数据对象包含我需要的一切,所以我排除了错误的响应(文本太大而无法复制,所以这是一个屏幕截图,你会得到图片):
如果我不得不猜测,问题出在解析中,但我解析它的方式适用于第一个 link。我究竟能做些什么来调试呢?我已经并排比较了 json,就像我说的,响应之间的结构是相同的,只是内容不同。
如果您仔细阅读错误,您会发现它的描述性很强。所以,不要隐藏错误,就像您对 print("error, wtf")
所做的那样,而是 log/print 它:
do {
let animeData = try JSONDecoder().decode(AnimeData.self, from: data!)
} catch {
print(error)
}
错误是:
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))
我发现向后阅读错误更容易,即自下而上。
马上,您会发现问题是“找到了空值”——即您的模型没有可选的空值。
在哪里? CodingKeys(stringValue: "coverImage", intValue: nil)]
- 所以,coverImage
为空。
那是哪里? CodingKeys(stringValue: "attributes", intValue: nil)
- 在 attributes
下,您可能知道。
但是哪一个,因为它是数组元素的 属性? [CodingKeys(stringValue: "data", intValue: nil), _JSONKey(stringValue: "Index 4", intValue: 4)
- data
索引 4
的一个元素,即 data[4]
,这是第五个元素。
长话短说,至少有一个(但实际上是两个)Anime
对象的 attribute
属性 在“损坏”响应中有 coverImage: null
。要解决此问题,请将此 属性 设为可选:
class Attributes: Codable {
// other properties
let coverImage: CoverImage?
}