Skip to content

Instantly share code, notes, and snippets.

@highthem
Created August 28, 2019 09:08
Show Gist options
  • Save highthem/55e04e417ec6e2791a35d6119ef1e1e4 to your computer and use it in GitHub Desktop.
Save highthem/55e04e417ec6e2791a35d6119ef1e1e4 to your computer and use it in GitHub Desktop.
how to encode and decode a protocol
import Foundation
protocol Poi: Codable {
var type: PoiType { get }
}
enum PoiType: String, Codable {
case meter, signage
var metatype: Poi.Type {
switch self {
case .meter: return Meter.self
case .signage: return Signage.self
}
}
}
class Meter: Poi {
var type: PoiType { return .meter }
let meterType: String
let cost: Int
init(meterType: String, cost: Int) {
self.meterType = meterType
self.cost = cost
}
}
class Signage: Poi {
var type: PoiType { return .signage }
let days: String
let isFree: Bool
init(days: String, isFree: Bool) {
self.days = days
self.isFree = isFree
}
}
struct PoiWrapper {
var poi: Poi
}
extension PoiWrapper: Codable {
private enum CodingKeys: CodingKey {
case type, poi
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
let type = try container.decode(PoiType.self, forKey: .type)
self.poi = try type.metatype.init(from: container.superDecoder(forKey: .poi))
}
func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(poi.type, forKey: .type)
try poi.encode(to: container.superEncoder(forKey: .poi))
}
}
// ————————————————————————
// testing
let pois: [Poi] = [Meter(meterType: "Single", cost: 12), Signage(days: "Su, Mo, Fr", isFree: false)]
let wrappedPois: [PoiWrapper] = pois.map { PoiWrapper(poi: $0) }
let data = try JSONEncoder().encode(wrappedPois)
let json = String(data: data, encoding: .utf8)
dump(json ?? "no json found!!!")
let originalWrappers = try JSONDecoder().decode([PoiWrapper].self, from: data)
let originalObjects = originalWrappers.map { $0.poi }
dump(originalObjects)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment