Skip to content

Instantly share code, notes, and snippets.

View Kdan's full-sized avatar

Kewin Remeczki Kdan

  • Copenhagen, Denmark
View GitHub Profile
@Kdan
Kdan / 1.swift
Last active April 10, 2018 16:51
class Pet: Codable {
let name: String
}
class Cat: Pet {
var lives: Int
}
class Dog: Pet {
func fetch() { /**/ }
}
@Kdan
Kdan / 1.json
Last active April 10, 2018 16:53
{
"name": "Kewin",
"pets": [
{
"type": "Cat",
"name": "Garfield",
"lives": 9
},
{
"type": "Dog",
@Kdan
Kdan / 2.swift
Last active April 10, 2018 19:00
class Person: Codable {
let name: String
/// Retrieve the pets of the Person.
func getPets(completion: ([Pet]) -> Void) throws {
// Networking request omitted for simplicity.
let data = responseData
completion(try JSONDecoder().decode([Pet].self, from: data))
}
}
@Kdan
Kdan / 3.swift
Last active April 10, 2018 18:15
/// To support a new class family, create an enum that conforms to this protocol and contains the different types.
protocol ClassFamily: Decodable {
/// The discriminator key.
static var discriminator: Discriminator { get }
/// Returns the class type of the object coresponding to the value.
func getType() -> AnyObject.Type
}
/// Discriminator key enum used to retrieve discriminator fields in JSON payloads.
/// The PetFamily enum describes the Pet family of objects.
enum PetFamily: String, ClassFamily {
case cat = "Cat"
case dog = "Dog"
static var discriminator: Discriminator = .type
func getType() -> AnyObject.Type {
switch self {
case .cat:
@Kdan
Kdan / 5.swift
Last active April 10, 2018 18:27
class ClassWrapper<T: ClassFamily, U: Decodable>: Decodable {
/// The family enum containing the class information.
let family: T
// The decoded object. Can be any subclass of U.
let object: U?
required init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: Discriminator.self)
// Decode the family with the discriminator.
family = try container.decode(T.self, forKey: T.discriminator)
@Kdan
Kdan / 6.swift
Last active April 10, 2018 19:00
class Person: Codable {
let name: String
/// Retrieve the pets of the Person.
func getPets(completion: ([Pet]) -> Void) throws {
// Networking request omitted for simplicity.
let data = responseData
completion(try JSONDecoder().decode([ClassWrapper<PetFamily, Pet>].self, from: data).compactMap { $0.object })
}
@Kdan
Kdan / 7.swift
Last active February 18, 2019 22:06
extension JSONDecoder {
/// Decode a heterogeneous list of objects.
/// - Parameters:
/// - family: The ClassFamily enum type to decode with.
/// - data: The data to decode.
/// - Returns: The list of decoded objects.
func decode<T: ClassFamily, U: Decodable>(family: T.Type, from data: Data) throws -> [U] {
return try self.decode([ClassWrapper<T, U>].self, from: data).compactMap { $0.object }
}
}
@Kdan
Kdan / 8.swift
Last active February 18, 2019 22:07
/// Retrieve the pets of the Person.
func getPets(completion: ([Pet]) -> Void) throws {
// Networking request omitted for simplicity.
if let data = responseData {
completion(try JSONDecoder().decode(family: PetFamily.self, from: data))
}
}
@Kdan
Kdan / heterogeneous_decoding.swift
Last active February 13, 2022 21:27
A Playground with an example of decoding a heterogeneous collection directly as a return type.
import Foundation
// MARK: - Model classes
/// The Pet superclass.
class Pet: Codable {
/// The name of the pet.
let name: String
enum CodingKeys: String, CodingKey {
case name