Enumeration Case

JSONDecoder.KeyDecodingStrategy.custom(_:)

A key decoding strategy defined by the closure you supply.

Declaration

case custom(([CodingKey]) -> CodingKey)

Discussion

The value associated with this case is a closure you use to map names of keys from the decoded JSON object to the names of your type's coding keys. During decoding, the closure is called once for each key in the Decodable value being decoded. The closure is called along with an array of CodingKey instances representing the sequence of keys needed to reach the value being decoded.

The example below shows how to decode the properties of the nested A, B, and C structures with custom logic that you specify in the closure value associated with the custom case.

struct A: Codable {
    var value: Int
    var b: B
    
    struct B: Codable {
        var value: Int
        var c: C
        
        struct C: Codable {
            var value: Int
        }
    }
}

let json = """
{
    "a.value": 1,
    "b": {
        "a.b.value": 2,
        "c": {
            "a.b.c.value": 3
        }
    }
}
""".data(using: .utf8)!

let decoder = JSONDecoder()

/// An implementation of CodingKey that's useful for combining and transforming keys as strings.
struct AnyKey: CodingKey {
    var stringValue: String
    var intValue: Int?
    
    init?(stringValue: String) {
        self.stringValue = stringValue
        self.intValue = nil
    }
    
    init?(intValue: Int) {
        self.stringValue = String(intValue)
        self.intValue = intValue
    }
}

In the next example you use the AnyKey structure defined above to customize the decoding of the A, B, and C structures.

// Customize each key to remove any preceding, dot-syntax paths.
decoder.keyDecodingStrategy = .custom { keys in
    let lastComponent = keys.last!.stringValue.split(separator: ".").last!
    return AnyKey(stringValue: String(lastComponent))!
}

let a = try decoder.decode(A.self, from: json)

print(a.b.c.value) // Prints "3"

Beta Software

This documentation contains preliminary information about an API or technology in development. This information is subject to change, and software implemented according to this documentation should be tested with final operating system software.

Learn more about using Apple's beta software