【问题标题】:Decode a PascalCase JSON with JSONDecoder使用 JSONDecoder 解码 PascalCase JSON
【发布时间】:2020-03-18 19:32:38
【问题描述】:

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

{
    "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 格式。

【问题讨论】:

    标签: json swift uppercase codable decodable


    【解决方案1】:

    我发现一个不错的解决方案是创建一个类似于 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 上的完整示例

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-02-06
      • 1970-01-01
      • 2020-05-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-01-07
      • 2020-08-27
      相关资源
      最近更新 更多