Last active
February 26, 2024 14:47
-
-
Save MojtabaHs/1f9a0f19bafaecd0c94f585648244303 to your computer and use it in GitHub Desktop.
Strategy for decoding UpperCamelCase JSONs to preferred lowerCamelCase version.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public extension JSONDecoder.KeyDecodingStrategy { | |
/// Convert from "UpperCamelCaseKeys" to "lowerCamelCaseKeys" before attempting to match a key with the one specified by each type. | |
/// | |
/// The conversion to upper case uses `Locale.system`, also known as the ICU "root" locale. This means the result is consistent regardless of the current user's locale and language preferences. | |
/// | |
/// - Copyright: This function is based on this [source](https://gist.github.com/MojtabaHs/1f9a0f19bafaecd0c94f585648244303) | |
static var convertFromUpperCamelCase: Self { | |
.custom { keys in | |
/// - Precondition: `Keys` array must never be empty. | |
guard let key = keys.last else { fatalError("Keys should not be empty") } | |
/// - Important: `Integer key`means that the json is a first level array. Do not change the key for an array! | |
guard key.intValue == nil else { return key } | |
let codingKeyType = type(of: key) | |
let lowerCamelCased = key.stringValue.lowercased(first: 1) | |
/// - Precondition: There should be no issues to initialize a new coding key. | |
guard let transformedKey = codingKeyType.init(stringValue: lowerCamelCased) else { | |
fatalError("Could not initialize a coding key for \"\(lowerCamelCased)\"") | |
} | |
return transformedKey | |
} | |
} | |
} | |
public extension String { | |
func lowercased(first count: Int) -> String { | |
prefix(count).lowercased() + dropFirst(count) | |
} | |
} | |
// USAGE: | |
/* | |
let jsonDecoder: JSONDecoder = { | |
let decoder = JSONDecoder() | |
decoder.keyDecodingStrategy = .convertFromUpperCamelCase | |
return decoder | |
}() | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment