The simplest is to have 2 var, one Int the other String
struct PlayerStats: Decodable {
var name: String
var valueI: Int? = nil // here String or Int
var valueS: String? = nil
}
let stat1 = PlayerStats(name: "One", valueI: 10)
let stat2 = PlayerStats(name: "Two", valueS: "Some value")
You can also create an enum as described here:
https://stackoverflow.com/questions/48297263/how-to-use-any-in-codable-type
enum QuantumValue: Decodable {
case int(Int)
case string(String)
init(from decoder: Decoder) throws {
if let int = try? decoder.singleValueContainer().decode(Int.self) {
self = .int(int)
return
}
if let string = try? decoder.singleValueContainer().decode(String.self) {
self = .string(string)
return
}
throw QuantumError.missingValue
}
enum QuantumError:Error {
case missingValue
}
}
struct PlayerStats: Decodable {
var name: String
var value: QuantumValue
}
let stat1 = PlayerStats(name: "One", value: QuantumValue.int(10))
let stat2 = PlayerStats(name: "Two", value: QuantumValue.string("Some value"))
Or a variation of it:
struct PlayerStats: Decodable {
var name: String = ""
var value: Any? = nil
init(name: String, valueInt: Int) {
self.name = name
self.value = valueInt
}
init(name: String, valueString: String) {
self.name = name
self.value = valueString
}
init(from decoder: Decoder) throws {
if let int = try? decoder.singleValueContainer().decode(Int.self) {
self.value = int
return
}
if let string = try? decoder.singleValueContainer().decode(String.self) {
self.value = string
return
}
}
}
let stat1 = PlayerStats(name: "One", valueInt: 10)
let stat2 = PlayerStats(name: "Two", valueString: "Some value")