Skip to content

Instantly share code, notes, and snippets.

@amrangry
Created June 15, 2020 10:19
Show Gist options
  • Save amrangry/89097b86514b3477cae79dd28bba3f23 to your computer and use it in GitHub Desktop.
Save amrangry/89097b86514b3477cae79dd28bba3f23 to your computer and use it in GitHub Desktop.
//
// ValueWrapper.swift
// ADKATech.com
//
// Created by Amr Elghadban on 9/20/18.
// Copyright © 2018 Mobile DevOps. All rights reserved.
//
import Foundation
enum ValueWrapper: Codable {
case stringValue(String)
case intValue(Int)
case doubleValue(Double)
case boolValue(Bool)
init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
if let value = try? container.decode(String.self) {
self = .stringValue(value)
return
}
if let value = try? container.decode(Bool.self) {
self = .boolValue(value)
return
}
if let value = try? container.decode(Double.self) {
self = .doubleValue(value)
return
}
if let value = try? container.decode(Int.self) {
self = .intValue(value)
return
}
throw DecodingError.typeMismatch(ValueWrapper.self, DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "Wrong type for ValueWrapper"))
}
func encode(to encoder: Encoder) throws {
var container = encoder.singleValueContainer()
switch self {
case let .stringValue(value):
try container.encode(value)
case let .boolValue(value):
try container.encode(value)
case let .intValue(value):
try container.encode(value)
case let .doubleValue(value):
try container.encode(value)
}
}
var rawValue: String {
var result: String
switch self {
case let .stringValue(value):
result = value
case let .boolValue(value):
result = String(value)
case let .intValue(value):
result = String(value)
case let .doubleValue(value):
result = String(value)
}
return result
}
var intValue: Int? {
var result: Int?
switch self {
case let .stringValue(value):
result = Int(value)
case let .intValue(value):
result = value
case let .boolValue(value):
result = value ? 1 : 0
case let .doubleValue(value):
result = Int(value)
}
return result
}
var boolValue: Bool? {
var result: Bool?
switch self {
case let .stringValue(value):
result = Bool(value)
case let .boolValue(value):
result = value
case let .intValue(value):
result = Bool(truncating: value as NSNumber)
case let .doubleValue(value):
result = Bool(truncating: value as NSNumber)
}
return result
}
}
@amrangry
Copy link
Author

@BenShutt
It good question, actually the usage of parsed value will vary according to your code needs,
let back again to the main pain that leads me to such a solution is actually that sometimes the response from API come as String or Int for the same parameter
for example :
[ { "name": "Amr", "age": "29" }, { "name": "Ben", "age": 28 } ]
the problem now how you would parse this, my solution is to decode using this helper type
then the usage depends on your business logic

@hhg23121998
Copy link

thank you so much, you safe my life ^^

@amrangry
Copy link
Author

amrangry commented Oct 14, 2021

thank you so much, you safe my life ^^

You are most welcome @hhg21011998, glad that it helps

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment