My main goal is to extract from a JSON file a value or an array of values identified by a keyPath. On macOS I have created the following method for this.
extension JSONDecoder
{
func decode<T: Decodable>(_ type: T.Type, from data: Data, keyPath: String) throws -> T
{
// Create Foundation object for the entire JSON data
let toplevel = try JSONSerialization.jsonObject(with: data)
// Extract part identified by the given keyPath
if let nestedJson = (toplevel as AnyObject).value(forKeyPath: keyPath)
{
// Create a data-object from that part
let nestedJsonData = try JSONSerialization.data(withJSONObject: nestedJson)
// Try to create an object of the given type from the data-object
return try decode(type, from: nestedJsonData)
}
else
{
throw DecodingError.dataCorrupted(.init(codingPath: [], debugDescription: "Nested json not found for key path \"\(keyPath)\""))
}
}
}
For example, this allows me to extract an array of strings with the keyPath [email protected]
by doing something like
if let categories = try JSONDecoder().decode([String].self, from: data, keyPath: keyPath)
{
}
Unfortunately the function func value(forKeyPath keyPath: String) -> Any?
is not available under Linux and I am now looking for an alternative.