Skip to content

Instantly share code, notes, and snippets.

@proxpero
Created July 17, 2017 19:08

Revisions

  1. proxpero created this gist Jul 17, 2017.
    85 changes: 85 additions & 0 deletions Barcode2.swift
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,85 @@
    // Accompanying blog post: http://127.0.0.1:4000/2017/07/11/encoding-and-decoding-custom-enums-with-associated-values-in-swift-4
    // Also: https://gist.github.com/proxpero/189a723fb96bb88fac5bf9e11d6cf9e2
    enum Barcode {
    case upc(Int, Int, Int, Int)
    case qrCode(String)
    }

    extension Barcode: Codable {

    private enum CodingKeys: String, CodingKey {
    case upc
    case qrCode
    }

    enum CodingError: Error {
    case decoding(String)
    }

    init(from decoder: Decoder) throws {
    let values = try decoder.container(keyedBy: CodingKeys.self)
    if let codes = try? values.decode(Array<Int>.self, forKey: .upc), codes.count == 4 {
    self = .upc(codes[0], codes[1], codes[2], codes[3])
    return
    }

    if let code = try? values.decode(String.self, forKey: .qrCode) {
    self = .qrCode(code)
    return
    }

    throw CodingError.decoding("Decoding Error: \(dump(values))")
    }

    func encode(to encoder: Encoder) throws {
    var container = encoder.container(keyedBy: CodingKeys.self)
    switch self {
    case .upc(let numberSystem, let manufacturer, let product, let check):
    try container.encode([numberSystem, manufacturer, product, check], forKey: .upc)
    case .qrCode(let productCode):
    try container.encode(productCode, forKey: .qrCode)
    }
    }
    }


    import Foundation

    let encoder = JSONEncoder()
    encoder.outputFormatting = .prettyPrinted
    let decoder = JSONDecoder()
    var productBarcode: Barcode
    var data: Data
    var json: String
    var expectation: String
    var result: Barcode

    productBarcode = .upc(8, 85909, 51226, 3)
    data = try encoder.encode(productBarcode)
    json = String.init(data: data, encoding: .utf8)!
    expectation = """
    {
    "upc" : [
    8,
    85909,
    51226,
    3
    ]
    }
    """
    print(json)
    result = try decoder.decode(Barcode.self, from: data)
    //assert(result == productBarcode)


    productBarcode = .qrCode("ABCDEFGHIJKLMNOP")
    data = try encoder.encode(productBarcode)
    json = String.init(data: data, encoding: .utf8)!
    expectation = """
    {
    "qrCode" : "ABCDEFGHIJKLMNOP"
    }
    """
    result = try decoder.decode(Barcode.self, from: data)
    assert(json == expectation)
    ////assert(result == productBarcode)