JSONDecoder 解析不连贯
Posted
技术标签:
【中文标题】JSONDecoder 解析不连贯【英文标题】:JSONDecoder parsing incoherence 【发布时间】:2021-07-19 21:01:07 【问题描述】:我在解码 JSON 文件时遇到了问题。
文件结构如下:
"grocery":
[
"vegetables":
"quantity":"some",
"compostable":true,
"stockageSite":"string",
"package":"bag"
,
"meats":
"quantity":"string",
"compostable":true,
"stockageSite":"string",
"package":"box"
,
"site":"string",
"active":true,
"name":"string"
]
我有以下结构
struct Goods: Codable
var quantity: String
var compostable: Bool
var stockageSite: String
var package: String
struct Details: Codable
var vegetables: Goods
var meats: Goods
var site: String
var active: Bool
var name: String
struct Grocery: Codable
var grocery: [Details]
解码(do-catch with
URLSession.shared.dataTask(with: request)data, response, error in
if let error = error
print("Error took place: \(error)")
return
if let response = response as? HTTPURLResponse
if response.statusCode != 200
print("Response HTTP Status code: \(response.statusCode)")
if let data = data
let decoder = JSONDecoder()
do
let jsonParse: Grocery = try decoder.decode(Grocery.self, from: data)
print("parsed \(jsonParse)")
catch let jsonError as NSError
print("Failed \(jsonError)")
) 解析得非常好,只要我从商品中删除“数量”或“库存站点”或“包装”(-> 即具有字符串值的那些,就像超过 2 个字符串项一样)在那里不起作用)。否则,没有解析并且代码执行在那里停止。没有抛出错误(游乐场除外:
error: Execution was interrupted, reason: EXC_BAD_ACCESS (code=EXC_I386_GPFLT)
字符串类型很好,没有错别字。 “可堆肥”(bool)是公认的。
(如果我将字符串元素添加到“详细信息”并相应地更改我的 json,也会发生同样的事情。)
这里是正确解析后打印的结果(3个字符串元素中的哪个被删除,所以“包”可以正确解析):
解析的杂货(杂货:[__lldb_expr_5.Details(蔬菜:__lldb_expr_5.Goods(数量:“一些”,可堆肥:true,stockageSite:“字符串”),肉类:__lldb_expr_5.Goods(数量:“字符串”,可堆肥: true, stockageSite: "string"), site: "string", active: true, name: "string")])
并且(有时!但为什么?!)打印的错误消息:
失败的 Swift.DecodingError.valueNotFound(__lldb_expr_7.Details, Swift.DecodingError.Context(codingPath: [CodingKeys(stringValue: "grocery", intValue: nil), _JSONKey(stringValue: "Index 0", intValue: 0), _JSONKey(stringValue: "Index 0", intValue: 0)], debugDescription: "预期的详细信息,但发现为空。",底层错误:nil))
就像从未找到第三个字符串元素一样。你能知道发生了什么吗?
【问题讨论】:
您创建错误变量并打印它吗? do // ... catch (let error) print(error) "解析非常好,没有抛出错误" 怎么样?一个叫“数据”的人是从哪里来的? 将它们声明为可选 为上面的 cmets 编辑了我的问题。可选不会改变任何东西。将数据打印为字符串显示值存在。 @NightCoder 显示您的实际 JSON。如果您发布没有任何意义的 JSON,没有人能够提供帮助。至少添加你说你正在捕捉的错误。 【参考方案1】:问题需要更多信息,但我猜这些对象中的键有时会丢失,所以这里是您如何处理它,只需使用 init(from decoder: Decoder)
并使用 decodeIfPresent
为丢失的键提供默认值更改您的 @ 987654323@ 结构到这个
struct Goods: Codable
var quantity: String
var compostable: String
var stockageSite: String
private enum CodingKeys: String, CodingKey
case quantity
case compostable
case stockageSite
init(from decoder: Decoder) throws
let container = try decoder.container(keyedBy: CodingKeys.self)
self.quantity = try container.decodeIfPresent(String.self, forKey: .quantity) ?? "Empty"
self.compostable = try container.decodeIfPresent(String.self, forKey: .compostable) ?? "Empty"
self.stockageSite = try container.decodeIfPresent(String.self, forKey: .stockageSite) ?? "Empty"
【讨论】:
谢谢!但是 JSON 是本地文件,没有丢失键 你试过了吗?答案 并使这两个键可选 我做了......不幸的是没有变化:(以上是关于JSONDecoder 解析不连贯的主要内容,如果未能解决你的问题,请参考以下文章
如何在 iOS 中解析没有 JSONdecoder 的 JSON 对象? [复制]
为啥 JsonDecoder 在尝试解析邮递员网址但处理其他网址时出现错误?
告诉 numberOfRowsInSection 在使用 MVVM 架构在闭包中使用 JSONDecoder 解析 JSON 后它需要多少行