Last active
October 26, 2021 18:31
-
-
Save tadija/69055043ee29afe736ae979d0d6a7645 to your computer and use it in GitHub Desktop.
AEJSONSerialization
This file contains hidden or 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
/** | |
* https://gist.github.com/tadija/69055043ee29afe736ae979d0d6a7645 | |
* Revision 3 | |
* Copyright © 2018-2021 Marko Tadić | |
* Licensed under the MIT license | |
*/ | |
import Foundation | |
public extension Data { | |
init(withJSONObject object: Any) throws { | |
if JSONSerialization.isValidJSONObject(object) { | |
self = try JSONSerialization.data( | |
withJSONObject: object, | |
options: .prettyPrinted | |
) | |
} else { | |
print("IMPORTANT ⚠️ Error while creating data from JSON!") | |
throw JSONError.invalidObject | |
} | |
} | |
func toDictionary() throws -> [String: Any] { | |
try serializeJSON() | |
} | |
func toArray() throws -> [Any] { | |
try serializeJSON() | |
} | |
private func serializeJSON<T>() throws -> T { | |
let jsonObject = try JSONSerialization.jsonObject( | |
with: self, options: .allowFragments | |
) | |
guard let parsed = jsonObject as? T else { | |
throw JSONError.serializationFailed | |
} | |
return parsed | |
} | |
} | |
public extension Decodable { | |
init(from dictionary: [String: Any]) throws { | |
let data = try Data(withJSONObject: dictionary) | |
self = try JSONDecoder().decode(Self.self, from: data) | |
} | |
init(from array: [Any]) throws { | |
let data = try Data(withJSONObject: array) | |
self = try JSONDecoder().decode(Self.self, from: data) | |
} | |
} | |
public extension Encodable { | |
func toDictionary() throws -> [String: Any] { | |
try jsonData().toDictionary() | |
} | |
func toArray() throws -> [Any] { | |
try jsonData().toArray() | |
} | |
func jsonData() throws -> Data { | |
try JSONEncoder().encode(self) | |
} | |
} | |
public extension Dictionary where Key: ExpressibleByStringLiteral { | |
func codable<T: Codable>(forKey key: String) throws -> T { | |
guard let value = self[key as! Key] else { | |
throw JSONError.valueMissing(forKey: key) | |
} | |
guard let dict = value as? [String : Any] else { | |
throw JSONError.valueTypeWrong(forKey: key) | |
} | |
let data = try Data(withJSONObject: dict) | |
return try JSONDecoder().decode(T.self, from: data) | |
} | |
func codableArray<T: Codable>(forKey key: String) throws -> [T] { | |
guard let value = self[key as! Key] else { | |
throw JSONError.valueMissing(forKey: key) | |
} | |
guard let array = value as? [[String : Any]] else { | |
throw JSONError.valueTypeWrong(forKey: key) | |
} | |
let data = try Data(withJSONObject: array) | |
return try JSONDecoder().decode([T].self, from: data) | |
} | |
} | |
public enum JSONError: Error { | |
case invalidObject | |
case valueMissing(forKey: String) | |
case valueTypeWrong(forKey: String) | |
case serializationFailed | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment