Last active
May 28, 2021 13:55
-
-
Save morteza2128/91ece213cfa399351689b238b1fc9dce to your computer and use it in GitHub Desktop.
AnyDecodable.swift
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
extension KeyedDecodingContainer { | |
typealias AnyDictionaryType = Dictionary<String, Any>.Type | |
typealias AnyArrayType = Array<Any>.Type | |
typealias AnyArrayOfDictionariesType = Array<Dictionary<String, Any>>.Type | |
// Decode Dictionary<String, Any> | |
func decode(_ type: AnyDictionaryType, forKey key: KeyedDecodingContainer<K>.Key) throws -> Dictionary<String, Any> { | |
let container = try self.nestedContainer(keyedBy: AnyCodingKeys.self, forKey: key) | |
return try container.decode(type) | |
} | |
func decodeIfPresent(_ type: AnyDictionaryType, forKey key: KeyedDecodingContainer<K>.Key) throws -> Dictionary<String, Any>? { | |
guard contains(key) else { return nil } | |
guard try decodeNil(forKey: key) == false else { return nil } | |
let decoded = try decodeIfPresent(type, forKey: key) | |
return decoded | |
} | |
// Decode Array<Any> | |
func decode(_ type: AnyArrayType, forKey key: KeyedDecodingContainer<K>.Key) throws -> Array<Any> { | |
var container = try self.nestedUnkeyedContainer(forKey: key) | |
return try container.decode(type) | |
} | |
func decodeIfPresent(_ type: AnyArrayType, forKey key: KeyedDecodingContainer<K>.Key) throws -> Array<Any>? { | |
guard contains(key) else { return nil } | |
guard try decodeNil(forKey: key) == false else { return nil } | |
return try decodeIfPresent(type, forKey: key) | |
} | |
// Decode Array<Dictionary<String, Any>> | |
func decode(_ type: AnyArrayOfDictionariesType, forKey key: KeyedDecodingContainer<K>.Key) throws -> Array<Dictionary<String, Any>> { | |
var container = try self.nestedUnkeyedContainer(forKey: key) | |
return try container.decode(type) | |
} | |
func decodeIfPresent(_ type: AnyArrayOfDictionariesType, forKey key: KeyedDecodingContainer<K>.Key) throws -> Array<Dictionary<String, Any>>? { | |
guard contains(key) else { return nil } | |
guard try decodeNil(forKey: key) == false else { return nil } | |
return try decodeIfPresent(type, forKey: key) | |
} | |
func decode(_ type: AnyDictionaryType) throws -> Dictionary<String, Any> { | |
var dictionary = Dictionary<String, Any>() | |
for key in allKeys { | |
if let boolValue = try? decode(Bool.self, forKey: key) { | |
dictionary[key.stringValue] = boolValue | |
} else if let stringValue = try? decode(String.self, forKey: key) { | |
dictionary[key.stringValue] = stringValue | |
} else if let intValue = try? decode(Int.self, forKey: key) { | |
dictionary[key.stringValue] = intValue | |
} else if let doubleValue = try? decode(Double.self, forKey: key) { | |
dictionary[key.stringValue] = doubleValue | |
} else if let nestedDictionary = try? decode(Dictionary<String, Any>.self, forKey: key) { | |
dictionary[key.stringValue] = nestedDictionary | |
} else if let nestedArray = try? decode(Array<Any>.self, forKey: key) { | |
dictionary[key.stringValue] = nestedArray | |
} | |
} | |
return dictionary | |
} | |
func decodeIfPresent(_ type: AnyDictionaryType) throws -> Dictionary<String, Any>? { | |
var dictionary = Dictionary<String, Any>() | |
for key in allKeys { | |
if let boolValue = try decodeIfPresent(Bool.self, forKey: key) { | |
dictionary[key.stringValue] = boolValue | |
} else if let stringValue = try decodeIfPresent(String.self, forKey: key) { | |
dictionary[key.stringValue] = stringValue | |
} else if let intValue = try decodeIfPresent(Int.self, forKey: key) { | |
dictionary[key.stringValue] = intValue | |
} else if let doubleValue = try decodeIfPresent(Double.self, forKey: key) { | |
dictionary[key.stringValue] = doubleValue | |
} else if let nestedDictionary = try decodeIfPresent(Dictionary<String, Any>.self, forKey: key) { | |
dictionary[key.stringValue] = nestedDictionary | |
} else if let nestedArray = try decodeIfPresent(Array<Any>.self, forKey: key) { | |
dictionary[key.stringValue] = nestedArray | |
} | |
} | |
return dictionary | |
} | |
} | |
extension UnkeyedDecodingContainer { | |
typealias AnyDictionaryType = Dictionary<String, Any>.Type | |
typealias AnyArrayType = Array<Any>.Type | |
typealias AnyArrayOfDictionariesType = Array<Dictionary<String, Any>>.Type | |
mutating func decode(_ type: AnyArrayType) throws -> Array<Any> { | |
var array: [Any] = [] | |
while isAtEnd == false { | |
if try decodeNil() { | |
continue | |
} else if let value = try? decode(Bool.self) { | |
array.append(value) | |
} else if let value = try? decode(Double.self) { | |
array.append(value) | |
} else if let value = try? decode(String.self) { | |
array.append(value) | |
} else if let nestedDictionary = try? decode(Dictionary<String, Any>.self) { | |
array.append(nestedDictionary) | |
} else if let nestedArray = try? decode(Array<Any>.self) { | |
array.append(nestedArray) | |
} | |
} | |
return array | |
} | |
mutating func decodeIfPresent(_ type: AnyArrayType) throws -> Array<Any>? { | |
var array: [Any] = [] | |
while isAtEnd == false { | |
if try decodeNil() { | |
continue | |
} else if let value = try decodeIfPresent(Bool.self) { | |
array.append(value) | |
} else if let value = try decodeIfPresent(Double.self) { | |
array.append(value) | |
} else if let value = try decodeIfPresent(String.self) { | |
array.append(value) | |
} else if let nestedDictionary = try decodeIfPresent(Dictionary<String, Any>.self) { | |
array.append(nestedDictionary) | |
} else if let nestedArray = try decodeIfPresent(Array<Any>.self) { | |
array.append(nestedArray) | |
} | |
} | |
return array | |
} | |
mutating func decode(_ type: AnyArrayOfDictionariesType) throws -> Array<Dictionary<String, Any>> { | |
var array = [[String: Any]]() | |
while isAtEnd == false { | |
if try decodeNil() { | |
continue | |
} else if let nestedDictionary = try? decode(Dictionary<String, Any>.self) { | |
array.append(nestedDictionary) | |
} | |
} | |
return array | |
} | |
mutating func decode(_ type: AnyDictionaryType) throws -> Dictionary<String, Any> { | |
let nestedContainer = try self.nestedContainer(keyedBy: AnyCodingKeys.self) | |
return try nestedContainer.decode(type) | |
} | |
mutating func decodeIfPresent(_ type: AnyDictionaryType) throws -> Dictionary<String, Any>? { | |
let nestedContainer = try self.nestedContainer(keyedBy: AnyCodingKeys.self) | |
return try nestedContainer.decodeIfPresent(type) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment