Расшифруйте PascalCase JSON с помощью JSONDecoder - PullRequest
0 голосов
/ 18 марта 2020

Мне нужно декодировать 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.

1 Ответ

0 голосов
/ 18 марта 2020

Хорошее решение, которое я нашел, - создать KeyDecodingStrategy, аналогичный .convertFromSnakeCase, доступному в Foundation.

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)

Полный пример по Суть

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...