Skip to content

Instantly share code, notes, and snippets.

@morteza2128
Last active May 28, 2021 13:55
Show Gist options
  • Save morteza2128/91ece213cfa399351689b238b1fc9dce to your computer and use it in GitHub Desktop.
Save morteza2128/91ece213cfa399351689b238b1fc9dce to your computer and use it in GitHub Desktop.
AnyDecodable.swift
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