I am attempting to make a tree data structure obey the encodable protocol. The tree terminates in "some object" that obeys the protocol "Terminal". Terminal extends Codable.
Each node of the tree is a pair. It has a key, and a value. The value is either a pair, or a Terminal.
There are two main issues:
1) I would like this structure to encode to JSON such that
class Pair: Codable {
var key: String?
var value: Codable?
}
let outputSimple = Pair(key: "a test key", value: "a test value")
// encodes to
// {"a test key": "a test value"}
// whereas currently encodes to
// {}
let outputComplex = Pair(key: "a parent", value: Pair(key: "another pair", value: "a test value"))
// encodes to
// {"a parent": {"another pair", "a test value"}}
EDIT: part 2 might be confusing the issue slightly. To clarify issue above, if I had
class Pair: Codable {
var key: String
var value: String
}
let p = Pair(key:"foo", value: "bar")
how could I get it to output {"foo":"bar"} rather than {key:foo, value:bar}? I tried
override func encode(to encoder: Encoder) throws {
var container = encoder.unkeyedContainer()
container.encode(contentsOf: [key: value])
}
but get the error "Instance method 'encode(contentsOf:)' requires that '(key: _, value: _)' conform to 'Encodable'"
2) I was attempting the following but it doesn't appear to work. I get "Pair does not conform to protocol 'Decodable'"
protocol TreeNode: Codable {}
struct Pair: TreeNode {
var key: String?
var value: TreeNode?
}
extension String: TreeNode {}
This one I can get around by making TreeNode a class with Pair a subclass. It's also likely this is correct Swift behaviour. However, I wondered if more pairs of eyes could explain the issue. I assumed that as long as I ensured all values are either of type pair, or something else that obeys Codable then it would work.
Codable. You could simplify that to fit your need for aTree/Pair. - Dávid Pásztor