Skip to content

Instantly share code, notes, and snippets.

@sajjadsarkoobi
Last active September 7, 2022 09:09
Show Gist options
  • Save sajjadsarkoobi/9376dfee0f63e9da3483c1363dfa9078 to your computer and use it in GitHub Desktop.
Save sajjadsarkoobi/9376dfee0f63e9da3483c1363dfa9078 to your computer and use it in GitHub Desktop.
//
// anyCodabelValue.swift
// Sajjad Sarkoobi
//
// Created by Sajjad Sarkoobi on 6/8/20.
// Copyright © 2020 Sajjad Sarkoobi. All rights reserved.
// Email: sajjadsarkoobi@gmail.com
import Foundation
enum AnyCodableValue: Codable {
case integer(Int)
case string(String)
case float(Float)
case double(Double)
case boolean(Bool)
case null
init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
if let x = try? container.decode(Int.self) {
self = .integer(x)
return
}
if let x = try? container.decode(String.self) {
self = .string(x)
return
}
if let x = try? container.decode(Float.self) {
self = .float(x)
return
}
if let x = try? container.decode(Double.self) {
self = .double(x)
return
}
if let x = try? container.decode(Bool.self) {
self = .boolean(x)
return
}
if let x = try? container.decode(String.self) {
self = .string(x)
return
}
if container.decodeNil() {
self = .string("")
return
}
throw DecodingError.typeMismatch(AnyCodableValue.self, DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "Wrong type"))
}
func encode(to encoder: Encoder) throws {
var container = encoder.singleValueContainer()
switch self {
case .integer(let x):
try container.encode(x)
case .string(let x):
try container.encode(x)
case .float(let x):
try container.encode(x)
case .double(let x):
try container.encode(x)
case .boolean(let x):
try container.encode(x)
case .null:
try container.encode(self)
break
}
}
//Get safe Values
var stringValue: String {
switch self {
case .string(let s):
return s
case .integer(let s):
return "\(s)"
case .double(let s):
return "\(s)"
case .float(let s):
return "\(s)"
default:
return ""
}
}
var intValue: Int {
switch self {
case .integer(let s):
return s
case .string(let s):
return (Int(s) ?? 0)
case .float(let s):
return Int(s)
case .null:
return 0
default:
return 0
}
}
var floatValue: Float {
switch self {
case .float(let s):
return s
case .integer(let s):
return Float(s)
case .string(let s):
return (Float(s) ?? 0)
default:
return 0
}
}
var doubleValue: Double {
switch self {
case .double(let s):
return s
case .string(let s):
return (Double(s) ?? 0.0)
case .integer(let s):
return (Double(s))
case .float(let s):
return (Double(s))
default:
return 0.0
}
}
var booleanValue: Bool {
switch self {
case .boolean(let s):
return s
case .integer(let s):
return s == 1
case .string(let s):
let bool = (Int(s) ?? 0) == 1
return bool
default:
return false
}
}
}
@karthisiva
Copy link

How to use this function? When type does not know comes from server, should i have to access all type for single key?

@sajjadsarkoobi
Copy link
Author

@karthisiva you can check this Medium for more description:
Support multiple types in codable — swift

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