Skip to content

Instantly share code, notes, and snippets.

@RoshanNindrai
Created December 4, 2018 16:59
Show Gist options
  • Save RoshanNindrai/3154979e15b60a57a14320bf6197def7 to your computer and use it in GitHub Desktop.
Save RoshanNindrai/3154979e15b60a57a14320bf6197def7 to your computer and use it in GitHub Desktop.
Quick and dirty Swift DTO transformation layer
//
// Transformable.swift
// Transformable
//
// Created by Roshan Nindrai on 10/15/18.
// Copyright © 2018 Roshan Nindrai. All rights reserved.
//
import Foundation
import CoreData
/// Coder for decoding Resource from NSObject
struct Coder {
static let decoder = JSONDecoder()
static let encoder = JSONEncoder()
}
protocol Transformable: class {
associatedtype Destination: Codable
}
protocol Transformer {
func toDictionary() -> [AnyHashable: Any]
}
struct Transform<Source: Transformable>: Transformer {
let source: Source
}
extension Transform {
func transform<Destination: Codable>() -> Destination? where Destination == Source.Destination {
return try? Coder.decoder.decode(Destination.self,
from: JSONSerialization.data(withJSONObject: toDictionary(),
options: .prettyPrinted))
}
func toDictionary() -> [AnyHashable: Any] {
let mySource = Mirror(reflecting: source)
return mySource.children.reduce(into: [AnyHashable: Any]()) { dict, property in
if let propertyName = property.label {
if let value = property.value as? Transformer {
dict.updateValue(value.toDictionary(), forKey: propertyName)
} else {
dict.updateValue(property.value, forKey: propertyName)
}
}
}
}
}
struct Address: Codable {
let street: String
let city: String
}
struct Person: Codable {
let name: String
let address: Address
}
class AddressEntity: Transformable {
typealias Destination = Address
let street = "1333 powell st"
let city = "Emeryville"
}
class PersonEntity: Transformable {
typealias Destination = Person
let name: String
let address: Transform<AddressEntity>
init(name: String, address: Transform<AddressEntity>) {
self.name = name
self.address = address
}
}
let address = Transform(source: AddressEntity())
let person = Transform(source: PersonEntity(name: "Roshan", address: address))
print(person.transform())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment