A few questions about CodingKeys.

struct Meta: Codable {
    let isEnd: Bool
    
    enum CodingKeys: String, CodingKey {
        case isEnd = "is_end"
    }
}

let jsonStr = """
{
"is_end" : true
}
"""

let jsonData = jsonStr.data(using: .utf8)!

do {
    let decoder = JSONDecoder()
    decoder.keyDecodingStrategy = .convertFromSnakeCase
    let result = try decoder.decode(Meta.self, from: jsonData)
    print(result)
} catch {
    print(error)
}

Code written in the above manner will result in the corresponding error.

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

I think there is nothing wrong with the code. But why is the error occurring?

And, Can't the enum be named something other than CodingKeys? like this,

struct Meta: Codable {
    let isEnd: Bool
    
    enum CodingKeyss: String, CodingKey {
        case isEnd = "is_end"
    }
}

And these codes return normal results. What's the reason

Meta(isEnd: true)

Replies

Try removing the decoder.keyDecodingStrategy = .convertFromSnakeCase line. You are already supplying an explicit key mapping via enum CodingKeys, so you don’t want the decoder to attempt to perform additional conversion on top of your mapping.

Can't the enum be named something other than CodingKeys?

CodingKeys is a special name recognized by the compiler to indicate that you have taken charge of defining the key mapping. So enum CodingKeyss will be ignored and the compiler will synthesize its own version of CodingKeys based on your property names. That, combined with the convertFromSnakeCase strategy, ends up performing the same name mapping that your explicit enum CodingKeys performs.