Swift中如何用Decodable协议同时解码小写与帕斯卡命名的JSON?
问题:Swift CodingKeys无法同时兼容小写与帕斯卡命名的JSON字段
我之前通过定义如下CodingKeys枚举,借助Swift的Decodable协议可以同时解码小写命名(如"bars")和帕斯卡命名(如"Bars")的JSON:
enum CodingKeys: String, CodingKey { case bars = "Bars" }
这种写法曾支持解码{"bars":[]}或{"Bars":[]}两种格式的JSON,但现在无法正常工作了。
以下是完整示例代码,运行后仅含帕斯卡命名字段的JSON能解码成功,小写命名的JSON只有在将CodingKeys改为小写或移除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))
我的旧项目中使用该CodingKeys方式仍能正常工作,因此怀疑当前示例存在错误,恳请指出问题所在。
内容的提问来源于stack exchange,提问作者Joel S.
相关产品推荐
相关产品推荐

