Decode "Any" and decoding keys arbitrarily
ftuckey-chwy opened this issue · 8 comments
I need to decode the following JSON, its keys could be anything
"DeviceStateVariables": {
"FanMode": "Auto",
"Mode": "CoolOn",
"Heating": 68,
"Cooling": 67,
"Temperature": 67
"AnyKey": AnyValue of AnyType
}
to get StateVariable objects like:
class StateVariable {
type: String
value: Any
}
StateVariable(type:"FanMode",value:"Auto")
StateVariable(type:"Mode",value:"CoolOn")
StateVariable(type:"Heating",value:68)
StateVariable(type:"Cooling",value:67)
StateVariable(type:"Temperature",value:67)
is this possible? AFAIK it is not possible to decode to Any and ecoding keys arbitrarily also isn't really well supported
Argo Version
Argo 3.0.0_
Hey @fedtuck, I think the easiest thing to do here would be to decode to [String: String]
then map over that to get your [StateVariables]
. Something like
let variables: Decoded<[String: String]> = json <| "DeviceStateVariables"
let states Decoded<[StateVariables]> = variables.map { vars in
vars.map { item in
let (key, value) = item
return StateVariable(type: key, value: value)
}
}
or you could fancy that up a bit to get
let variables: Decoded<[String: String]> = json <| "DeviceStateVariables"
let states Decoded<[StateVariables]> = variables.map { $0.map { StateVariable(type: $0.0, value: $0.1) } }
I think that should do it.
@tonyd256 thanks a lot for your help. The issue Im still having is that DeviceStateVariables is actually [String:Any], so I cannot use Decoded<[String: String]. Do you know any workaround for that?
If you conform Any
to Decodable
that should do the trick. That would mostly involve simply returning the value from all the cases of JSON
in the decode
function.
@tonyd256 Im trying to implement this, but the line
let variables: Decoded<[String: String]> = json <| "DeviceStateVariables"
doesn't work for me. I get an error
Do you happen to know what could it be?
hmm, this (
Argo/Argo/Types/StandardTypes.swift
Line 202 in f494b05
We don't have a definition of <|
that works with dictionaries. You'll need to do use decodeObject
instead:
let variables: Decoded<[String: String]> = (json <| "DeviceStateVariables").flatMap(decodeObject)
That should work for you.
@fedtuck any update here? Did that end up doing the trick?
I'm going to go ahead and close this due to inactivity but please feel free to reopen if this is still an issue.