<!--
{
  "availability" : [
    "iOS: 8.0.0 -",
    "iPadOS: 8.0.0 -",
    "macCatalyst: 8.0.0 -",
    "macOS: 10.10.0 -",
    "tvOS: 9.0.0 -",
    "visionOS: 1.0.0 -",
    "watchOS: 2.0.0 -"
  ],
  "documentType" : "symbol",
  "framework" : "Foundation",
  "identifier" : "/documentation/Foundation/JSONEncoder/KeyEncodingStrategy-swift.enum/custom(_:)",
  "metadataVersion" : "0.1.0",
  "role" : "Case",
  "symbol" : {
    "kind" : "Case",
    "modules" : [
      "Foundation"
    ],
    "preciseIdentifier" : "s:10Foundation11JSONEncoderC19KeyEncodingStrategyO6customyAEs06CodingC0_pSaysAG_pGccAEmF"
  },
  "title" : "JSONEncoder.KeyEncodingStrategy.custom(_:)"
}
-->

# JSONEncoder.KeyEncodingStrategy.custom(_:)

A key encoding strategy defined by the closure you supply.

```
@preconcurrency case custom(@Sendable ([any CodingKey]) -> any CodingKey)
```

## Parameters

`codingPath`

A closure that provides the full path to the current encoding position, and returns a customized coding key.

## Discussion

The value associated with this case is a closure you use to choose the names of keys in the encoded JSON object. During encoding, the closure executes once for each key in the <doc://com.apple.documentation/documentation/Swift/Encodable> value. The closure receives an array of <doc://com.apple.documentation/documentation/Swift/CodingKey> instances representing the sequence of keys needed to reach the value the encoder is currently encoding.

The example below shows how to encode 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.

```swift
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 a: A = A(value: 1, b: .init(value: 2, c: .init(value: 3)))

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

let encoder = JSONEncoder()
encoder.outputFormatting = [.prettyPrinted, .sortedKeys]
let encodeAndPrint = { print(String(data: try encoder.encode(a), encoding: .utf8) ?? "String encoding error.") }

/// 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 encoding of the `A`, `B`, and `C` structures.

```swift
// Customize each `value` key to contain a dot-syntax path.
encoder.keyEncodingStrategy = .custom { keys in
    if keys.last!.stringValue == "value" {
        return AnyKey(stringValue: "a." + keys.map { key in
            key.stringValue
        }.joined(separator: "."))!
    } else {
        return keys.last!
    }
}

try encodeAndPrint()
```

Here’s the JSON object that results from the custom encoding above:

```javascript
 {
     "a.value": 1,
     "b": {
         "a.b.value": 2,
         "c": {
            "a.b.c.value": 3
         }
     }
 }
```

---

Copyright &copy; 2026 Apple Inc. All rights reserved. | [Terms of Use](https://www.apple.com/legal/internet-services/terms/site.html) | [Privacy Policy](https://www.apple.com/privacy/privacy-policy)