As the question states: I have a struct conforming to the new Encodable
protocol and would like to insert keys and values that are not present as variables or constants in the struct itself. My current workaround is adding them to the struct as constants with the sole purpose of being added to the generated JSON output. Is there a way to accomplish this in func encode(to encoder: Encoder) throws { ... }
?
Background Information
I have a rather big Swift 4 project that needs a JSON output to generate statistics and visualizations outside the project itself, so nearly all of my structs, classes and enums conform to the new Encodable
protocol. The Output is already working, but the readability is bad at some points. Especially in one struct that describes a field in a rasterized factory layout:
The field has a position (with coordinates x: Int
and y: Int
) and content of a custom enum FieldType
containing the following cases:
case wall
case entrance(robots: Set<Robot>)
case exit(robots: Set<Robot>)
case workstation(object: Workstation)
case robot(object: Robot)
case empty
Position
, FieldType
, Robot
, Workstation
and the Field
itself already implement Encodable
, but the problem is that my JSON output for the fields looks like this:
...
{
"content" : "empty",
"position" : {
"x" : 9,
"y" : 6
}
},
{
"content" : "empty",
"position" : {
"x" : 10,
"y" : 6
}
},
{
"content" : {
"id" : 3,
"state" : "idle",
"type" : "C",
"position" : {
"x" : 11,
"y" : 6
}
},
"position" : {
"x" : 11,
"y" : 6
}
},
{
"content" : "empty",
"position" : {
"x" : 12,
"y" : 6
}
},
...
As you can see there is something other than an empty field at position (11, 6), but without knowing that only workstations have an idle state in my simulation, there is no way of knowing what content that field holds. So I tried adding a key "object"
with the value "workstation"
to my workstation model (analogical "robot"
in the robot model) by defining CodingKeys as an enum:
private enum CodingKeys: String, CodingKey {
case object
case id
case state
case type
case position
}
This results in my struct Workstation
no longer conforming to Encodable
. So the only solution I found was adding a constant let object = "workstation"
, but this is a constant with the sole purpose of being added to the output and I would like to avoid that.
You'll have to write a custom encoder for
FieldType
:(This assumes that
Robot
andWorkstation
are alreadyEncodable
)