Skip to content

Instantly share code, notes, and snippets.

@mbuchetics
Forked from reckenrode/codeableEnum.swift
Created June 30, 2017 09:30
Show Gist options
  • Save mbuchetics/5d5600c50c369bea29db4a3986cee94f to your computer and use it in GitHub Desktop.
Save mbuchetics/5d5600c50c369bea29db4a3986cee94f to your computer and use it in GitHub Desktop.

Revisions

  1. @reckenrode reckenrode created this gist Jun 23, 2017.
    62 changes: 62 additions & 0 deletions codeableEnum.swift
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,62 @@
    struct User: Codable {
    var name: String
    var email: String
    var id: String
    var metadata: [String: MetadataType]

    enum CodingKeys: String, CodingKey {
    case name, email, id, metadata
    }
    }

    enum MetadataType: Codable {
    case double(Double)
    case string(String)

    init(from decoder: Decoder) throws {
    let container = try decoder.singleValueContainer()
    do {
    self = try .double(container.decode(Double.self))
    } catch DecodingError.typeMismatch {
    do {
    self = try .string(container.decode(String.self))
    } catch DecodingError.typeMismatch {
    throw DecodingError.typeMismatch(MetadataType.self, DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "Encoded payload not of an expected type"))
    }
    }
    }

    func encode(to encoder: Encoder) throws {
    var container = encoder.singleValueContainer()
    switch self {
    case .double(let double):
    try container.encode(double)
    case .string(let string):
    try container.encode(string)
    }
    }
    }

    import Foundation

    let decoder = JSONDecoder()

    let userJson = """
    {
    "id": "4yq6txdpfadhbaqnwp3",
    "email": "[email protected]",
    "name":"John Doe",
    "metadata": {
    "link_id": "linked-id",
    "buy_count": 4
    }
    }
    """.data(using: .utf8)!

    let user = try! decoder.decode(User.self, from: userJson)
    print(user)

    let encoder = PropertyListEncoder()
    encoder.outputFormat = .xml
    let plist = try! encoder.encode(user)
    print(String(data: plist, encoding: .utf8)!)