简体   繁体   English

使用 JSONDecoder 解码 PascalCase JSON

[英]Decode a PascalCase JSON with JSONDecoder

I need to decode a JSON with uppercased first letters (aka PascalCase or UppperCamelCase) like this :我需要使用大写首字母(又名 PascalCase 或 UppperCamelCase)解码 JSON,如下所示:

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

So I created a model conforming to Codable :所以我创建了一个符合Codable的模型:

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

But JSONDecoder raises an error because the case is different.但是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))

I would like to keep my model's properties in camelCase but I can't change the JSON fomat.我想将模型的属性保留在驼峰式大小写中,但我无法更改 JSON 格式。

A nice solution I found is to create a KeyDecodingStrategy similar to the .convertFromSnakeCase available in Foundation.一个很好的解决方案,我发现是创建一个KeyDecodingStrategy类似.convertFromSnakeCase提供基础。

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()
    }
}

It can be used easily like so :它可以像这样轻松使用:

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

Full example on Gist Gist 上的完整示例

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM