create custom decoding strategy in swift

To create a custom decoding strategy in Swift, you need to create a class that conforms to the KeyDecodingStrategy protocol. The following example shows how to create a custom decoding strategy that converts snake_case keys to camelCase keys:

main.swift
class SnakeCaseToCamelCaseKeyDecodingStrategy: KeyDecodingStrategy {
    func key(fromCodingKey key: CodingKey) -> CodingKey {
        let snakeCaseKeyName = key.stringValue
        let components = snakeCaseKeyName.components(separatedBy: "_")
        let camelCaseKeyName = components.enumerated().reduce("", { (result, tuple) in
            let isFirstComponent = tuple.offset == 0
            let prefix = isFirstComponent ? "" : result
            let capitalizedComponent = tuple.element.capitalized
            return "\(prefix)\(capitalizedComponent)"
        })
        return AnyCodingKey(stringValue: camelCaseKeyName)!
    }
}
639 chars
14 lines

Once you have defined your custom key decoding strategy, you can use it to decode JSON data:

main.swift
let json = """
{
    "first_name": "John",
    "last_name": "Doe"
}
""".data(using: .utf8)!

struct Person: Codable {
    let firstName: String
    let lastName: String

    private enum CodingKeys: String, CodingKey {
        case firstName
        case lastName
    }

    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: AnyCodingKey.self)
        let strategy = SnakeCaseToCamelCaseKeyDecodingStrategy()
        firstName = try container.decode(String.self, forKey: strategy.key(fromCodingKey: CodingKeys.firstName))
        lastName = try container.decode(String.self, forKey: strategy.key(fromCodingKey: CodingKeys.lastName))
    }
}

let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .custom(SnakeCaseToCamelCaseKeyDecodingStrategy())
let person = try decoder.decode(Person.self, from: json)
print(person.firstName) // Output: "John"
print(person.lastName) // Output: "Doe"
932 chars
30 lines

In the above example, the Person struct defines two properties: firstName and lastName. The CodingKeys enum is used to map the firstName and lastName properties to their respective snake_case keys in the JSON data. The init(from:) method is where the custom key decoding strategy is applied to the container of the JSON data. The decode(_:forKey:) method is used to decode the individual properties using the custom decoding strategy.

related categories

gistlibby LogSnag