Imagine this data sample
"meta_data": [
{
"id": 40097,
"key": "_wcf_frm_created",
"value": ""
},
{
"id": 40098,
"key": "_wcf_custom_degin_checkbox",
"value": ""
},
{
"id": 40099,
"key": "_wcf_frm_data",
"value": {
"1": {
"1": "",
"2": "",
"3": "chk_box"
}
}
},
{
"id": 40119,
"key": "_vendor_select",
"value": "6484"
},
{
"id": 40120,
"key": "_vendor_percentage",
"value": "1"
},
{
"id": 40121,
"key": "_vendor_pro_cat",
"value": "Accessories"
}
]
the Value in Meta_data can have multiple types. In the generator I used shown that the data type should be created like this.
sealed class Value {
class StringMapMapValue(val value: Map<String, Map<String, String>>) : Value()
class StringValue(val value: String) : Value()
}
With Moshi, I understand you have to add @JsonClass(generateAdapter = true) on top of the data class. Thus I have something like this
@JsonClass(generateAdapter = true)
data class MetaDatum (
val id: Long,
val key: String,
val value: Value
)
@JsonClass(generateAdapter = true)
sealed class Value {
class StringMapMapValue(val value: Map<String, Map<String, String>>) : Value()
class StringValue(val value: String) : Value()
}
I would like to note that the full json is much bigger than this. However, this is the only issue I have. I had some Enum issues as well, but those can be replaced with String
The error I received is error: @JsonClass can't be applied to net......Activity.Value: must not be sealed public static abstract class Value
Thus my question is, how do i decode the json with multiple enum types.
Ill add this here, In xCode(swift) this was how i was manage to do it.
enum Value: Codable {
case string(String)
case stringMapMap([String: [String: String]])
init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
if let x = try? container.decode([String: [String: String]].self) {
self = .stringMapMap(x)
return
}
if let x = try? container.decode(String.self) {
self = .string(x)
return
}
throw DecodingError.typeMismatch(Value.self, DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "Wrong type for Value"))
}
func encode(to encoder: Encoder) throws {
var container = encoder.singleValueContainer()
switch self {
case .string(let x):
try container.encode(x)
case .stringMapMap(let x):
try container.encode(x)
}
}
}
Calling the data
fun retrieveMenu(sku: Int, SSLAuth: String)
{
doAsync {
val client = OkHttpClient().newBuilder()
.build()
val formBody: RequestBody = FormBody.Builder()
.build()
val request: Request = Request.Builder()
.url("https://carteapp.net/..................")
.method("Get", formBody)
.build()
client.newCall(request).execute().use { response ->
if (!response.isSuccessful) throw IOException("Unexpected code $response")
val gist =
gistJsonAdapter.fromJson(response.body!!.source())
println(gist)
}
}
}
private val moshi = Moshi.Builder().build()
private val gistJsonAdapter = moshi.adapter(BarcodeScannerActivity.WcProductCall::class.java)
@JsonClass(generateAdapter = true)
data class WcProductCall (
val id: Long,
...........
val metaData: List<MetaDatum>,
...
)