Maybe someone in the community has had similar struggles and have come up with a workable solution.
We're currently working on a polyglot key/value store. Given this, we'll generally have no knowledge of what will be stored ahead of time.
Consider the following struct
struct Character : Codable, Equatable {
let name: String
let age: Int
let gender: Gender
let hobbies: [String]
static func ==(lhs: Character, rhs: Character) -> Bool {
return (lhs.name == rhs.name
&& lhs.age == rhs.age
&& lhs.gender == rhs.gender
&& lhs.hobbies == rhs.hobbies)
}
}
When sending/receiving Character entities over the wire, everything is fairly straight forward. The user can provide us the Type in which we can decode into.
However, we do have the ability to dynamically query the entities stored within the backend. For example, we can request the value of the 'name' property and have that returned.
This dynamism is a pain point. In addition to not knowing the type of the properties outside of the fact that they are Codable, the format that is returned can be dynamic as well.
Here's some examples of response for two different calls extracting properties:
{"value":"Bilbo"}
and
{"value":["[Ljava.lang.Object;",["Bilbo",111]]}
In some cases, it could be an equivalent of a dictionary.
Right now, I have the following structs for dealing with responses:
fileprivate struct ScalarValue<T: Decodable> : Decodable {
var value: T?
}
Using the Character example, the type passed to the decoder would be:
ScalarValue<Character>.self
However, for the single value, array, or dictionary case, I'm somewhat stuck.
I've started with something like:
fileprivate struct AnyDecodable: Decodable {
init(from decoder: Decoder) throws {
// ???
}
}
Based on the possible return types I've described above, I'm not sure if this is possible with the current API.
Thoughts?