使用JSONDecoder解码PascalCase JSON



我需要解码一个带有大写首字母的JSON(又名PascalCase或UppperCamelCase(,如下所示:

{
"Title": "example",
"Items": [
"hello",
"world"
]
}

所以我创建了一个符合Codable:的模型

struct Model: Codable {
let title: String
let items: [String]
}

但是JSONDecoder由于情况不同而引发错误。

Swift.DecodingError.keyNotFound(CodingKeys(stringValue: "title", intValue: nil), Swift.DecodingError.Context(codingPath: [], debugDescription: "No value associated with key CodingKeys(stringValue: "title", intValue: nil) ("title").", underlyingError: nil))

我想在camelCase中保留我的模型属性,但我不能更改JSON格式。

我发现的一个不错的解决方案是创建一个类似于Foundation中可用的.convertFromSnakeCaseKeyDecodingStrategy

extension JSONDecoder.KeyDecodingStrategy {
static var convertFromPascalCase: JSONDecoder.KeyDecodingStrategy {
return .custom { keys -> CodingKey in
// keys array is never empty
let key = keys.last!
// Do not change the key for an array
guard key.intValue == nil else {
return key
}
let codingKeyType = type(of: key)
let newStringValue = key.stringValue.firstCharLowercased()
return codingKeyType.init(stringValue: newStringValue)!
}
}
}
private extension String {
func firstCharLowercased() -> String {
prefix(1).lowercased() + dropFirst()
}
}

它可以像这样简单地使用:

let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromPascalCase
let model = try! decoder.decode(Model.self, from: json)

Gist 的完整示例

相关内容

  • 没有找到相关文章

最新更新