Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@IanKeen
Created April 30, 2019 16:52
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save IanKeen/788e2ce55e5c91257bc639efc5dbb1c1 to your computer and use it in GitHub Desktop.
Save IanKeen/788e2ce55e5c91257bc639efc5dbb1c1 to your computer and use it in GitHub Desktop.
import Foundation
struct AnyCodingKey: CodingKey {
var stringValue: String
var intValue: Int?
init?(intValue: Int) {
self.intValue = intValue
self.stringValue = "\(intValue)"
}
init?(stringValue: String) {
self.intValue = nil
self.stringValue = stringValue
}
}
// MARK: - Identifier<T>
struct Identifier<T> {
let value: String
}
extension Identifier: Codable {
init(from decoder: Decoder) throws {
self.value = try String(from: decoder)
}
func encode(to encoder: Encoder) throws {
try value.encode(to: encoder)
}
}
// MARK: - Identified<T>
struct Identified<T> {
let identifier: Identifier<T>
let value: T
}
extension Identified: Codable where T: Codable {
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: AnyCodingKey.self)
self.identifier = try container.decode(Identifier<T>.self, forKey: AnyCodingKey(stringValue: "identifier")!)
self.value = try T.init(from: decoder)
}
func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: AnyCodingKey.self)
try container.encode(identifier, forKey: AnyCodingKey(stringValue: "identifier")!)
try value.encode(to: encoder)
}
}
// MARK: - Models
struct Author: Codable {
let name: String
}
struct Book: Codable {
let title: String
let authorIdentifier: Identifier<Author>
}
// MARK: - Usage
let authorJson = """
{
"identifier": "A13424B6",
"name": "Robert C. Martin"
}
""".data(using: .utf8)!
let bookJson = """
{
"identifier": "A161F15C",
"title": "Clean Code",
"authorIdentifier": "A13424B6"
}
""".data(using: .utf8)!
let author = try! JSONDecoder().decode(Identified<Author>.self, from: authorJson)
print("Author ID:", author.identifier.value)
print("Author Name:", author.value.name)
print("")
let book = try! JSONDecoder().decode(Identified<Book>.self, from: bookJson)
print("Book ID:", book.identifier.value)
print("Book Title:", book.value.title)
print("Book Author ID:", book.value.authorIdentifier.value)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment