How to decode/encode custom containers with different objects types in with Swift
How to decode/encode Github API event feed
Decoding automatically a custom object from json
When decoding an object like:
{
"type": "foo",
"payload": {
"word": "hello"
"push_id": 3711282988,
"size": 1,
}
}
With a struct implementing Codable
can be parsed easyly.
struct Payload: Codable {
var word: String
var push_id: Int
var size: Int
}
struct Foo: Codable {
var type: String
var payload: Payload
}
let decoder = JSONDecoder()
let product = try decoder.decode(Foo.self, from: json)
But what happens when one of the inner properties of an object, includes a type that can be different.
Decoding manualy a custom object from json
[{
"type": "foo",
"payload": {
"word": "hello"
"push_id": 3711282988,
"size": 1,
}
},
{
"type": "bar",
"payload": {
"size": 1,
"radious": 0.5
}
}]
In this case, the object cannot be parsed directly because the type of the payload object depends in the “type” property.
To solve this, the object must be decoded manually, this way.
struct FooPayload: Codable {
var word: String
var push_id: Int
var size: Int
}
struct BarPayload: Codable {
var size: Int
var radious: Double
}
struct Foo {
var type: String
var payload: Payload?
enum CodingKeys : CodingKey {
case type, payload
}
init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
type = try values.decode(String.self, forKey: .type)
swith type {
case "foo":
payload = values.decode(FooPayload.self, forKey: .payload)
case "bar":
payload = values.decode(BarPayload.self, forKey: .payload)
default:
payload = nil
}
}
}