直到最近,我已经能够使用Decodable协议来解码小写(“fooBar”)JSON和Pascal大小写(“FooBar”)JSON,只需包含一个像这样的CodingKeys枚举。
enum CodingKeys: String, CodingKey {
case bars = "Bars"
}
字符串
这允许我以以下两种形式之一解码JSON:{"bars":[]}
或{"Bars":[]}
但这对我不再有效。
完整的例子如下。当我运行这段代码时,只有具有Pascal大小写字段名的JSON被解码。解码小写JSON的唯一方法是将CodingKeys更改为小写(简单地匹配定义的字段名)或完全删除它们。
范例:
import UIKit
struct Foo: Codable {
var bars: [Bar]
enum CodingKeys: String, CodingKey {
case bars = "Bars"
}
struct Bar: Codable {
var barBaz: String
enum CodingKeys: String, CodingKey {
case barBaz = "BarBaz"
}
}
}
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let fooBars = [
"{\"bars\": [{\"barBaz\": \"abc\"}]}",
"{\"Bars\": [{\"BarBaz\": \"abc\"}]}",
"{\"Bars\": [{\"BarBaz\": \"abc\"},{\"BarBaz\": \"def\"}]}",
"{\"Bars\": []}",
"{\"bars\": []}"
]
fooBars.forEach {
if let fooBar = $0.data(using: .utf8) {
do {
let data = try JSONDecoder().decode(Foo.self, from: fooBar)
print("Success:\nFound \(data.bars.count) bar(s).\n")
} catch {
print("Fail:\n\(error)\n")
}
}
}
}
}
型
输出量:
Fail:
keyNotFound(CodingKeys(stringValue: "Bars", intValue: nil), Swift.DecodingError.Context(codingPath: [], debugDescription: "No value associated with key CodingKeys(stringValue: \"Bars\", intValue: nil) (\"Bars\").", underlyingError: nil))
Success:
Found 1 bar(s).
Success:
Found 2 bar(s).
Success:
Found 0 bar(s).
Fail:
keyNotFound(CodingKeys(stringValue: "Bars", intValue: nil), Swift.DecodingError.Context(codingPath: [], debugDescription: "No value associated with key CodingKeys(stringValue: \"Bars\", intValue: nil) (\"Bars\").", underlyingError: nil))
型
我的应用程序仍然使用这种CodingKey方法引用旧的Codable类。所以,我怀疑我在这个特定的例子中一定做错了什么。
有人能解释一下我做错了什么吗?
3条答案
按热度按时间3bygqnnd1#
我可以通过实现这样的自定义初始化器来实现这一点.
字符串
这允许我在解码时捕获值并将其解析为相应的属性。现在我可以将
{"bars":[]}
和"{Bars:[]}"
读入bars
属性。pkwftd7m2#
扩展Joel自己的答案。如果没有解码你的json,你的代码将默默地失败。不要使用try?忽略错误。你应该总是抓住它们。顺便说一句
data(using: .utf8)
永远不会失败。你可以安全地强制解包结果或使用Data non falible initializerData($0.utf8)
自定义解码器的正确实现应该是这样的:
字符串
jhkqcmku3#
这是一种不同的方法,使用自定义密钥解码策略,它使所有CodingKeys的第一个字符为
字符串
它需要一个自定义的CodingKey
型
现在应用该策略,它将删除
CodingKeys
枚举型