Created
October 26, 2021 11:01
-
-
Save samrayner/963fc5a9f3ed8a654d5bef217e2e7cfc to your computer and use it in GitHub Desktop.
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
import Foundation | |
///A type that can be encoded to a string-keyed dictionary. | |
public protocol DictionaryEncodable: Encodable {} | |
public protocol DictionaryDecodable: Decodable {} | |
///A type that can be encoded and decoded to/from a string-keyed dictionary. | |
public typealias DictionaryCodable = DictionaryEncodable & DictionaryDecodable | |
extension DictionaryEncodable { | |
/** | |
Returns a dictionary representation of the object's properties. | |
- Parameters: | |
- jsonEncoder: The encoder to use to encode the object's properties. | |
- Throws: `EncodingError` if the encoding fails. | |
- Returns: A dictionary representation of the object's properties. | |
*/ | |
public func dictionary(jsonEncoder: JSONEncoder = JSONEncoder()) throws -> [String: Any] { | |
let json = try jsonEncoder.encode(self) | |
guard let dictionary = try JSONSerialization.jsonObject(with: json, options: .allowFragments) as? [String: Any] else { | |
throw EncodingError.invalidValue(self, .init(codingPath: [], debugDescription: "Unable to convert to [String: Any]")) | |
} | |
return dictionary | |
} | |
} | |
extension DictionaryDecodable { | |
/** | |
Attempts to initialize an object from a dictionary of its property values. | |
- Parameters: | |
- dictionary: The dictionary containing the object's properties. | |
- jsonDecoder: The decoder to convert the keys and values to the object. | |
- Throws: `DecodingError` if decoding fails. | |
*/ | |
public init(dictionary: [String: Any], jsonDecoder: JSONDecoder = JSONDecoder()) throws { | |
guard JSONSerialization.isValidJSONObject(dictionary) else { | |
throw DecodingError.dataCorrupted(.init(codingPath: [], debugDescription: "Dictionary is not a valid JSON object.")) | |
} | |
let data = try JSONSerialization.data(withJSONObject: dictionary, options: []) | |
self = try jsonDecoder.decode(Self.self, from: data) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment