For my Android app I try to parse a network response using Kotlinx serialization. The network response is a WebSocket Payload from Kraken and looks like a JSON array, that has elements without keys. I want to create a data class for this response and assign the missing keys. The network response looks like this:
[
324,
{
"a": [
"65534.00000",
8,
"8.45840938"
],
"b": [
"65533.90000",
0,
"0.00352122"
],
"c": [
"65533.90000",
"0.00458332"
],
"v": [
"2282.41761567",
"3048.01677262"
],
"p": [
"65297.21555",
"64608.96127"
],
"t": [
27317,
38224
],
"l": [
"63319.60000",
"61810.00000"
],
"h": [
"66420.00000",
"66420.00000"
],
"o": [
"63319.60000",
"61962.00000"
]
},
"ticker",
"XBT/USD"
]
Finally I ended up with decoding the payload as JsonArray and feeding my Data Class with its content manually.
Here is my Data Class:
@Serializable
data class Ticker(
var channelID : String,
var channelName : String,
var pair : String,
var ticker : TickerData,
)
@Serializable
data class TickerData(
@SerialName("a")
val ask: Ask,
@SerialName("b")
val bid: Bid,
@SerialName("c")
val close: Close,
@SerialName("h")
val volume: Volume,
@SerialName("l")
val volumeWeightedAveragePrice: VolumeWeightedAveragePrice,
@SerialName("o")
val numberOfTrades: NumberOfTrades,
@SerialName("p")
val lowPrice: LowPrice,
@SerialName("t")
val highPrice: HighPrice,
@SerialName("v")
val openPrice: OpenPrice,
)
@Serializable
data class Ask(
var price: String,
var wholeLotVolume: Int,
var lotVolume: String,
)
@Serializable
data class Bid(
var price: String,
var wholeLotVolume: Int,
var lotVolume: String,
)
@Serializable
data class Close(
var price: String,
var lotVolume: String,
)
@Serializable
data class Volume(
var today: String,
var last24Hours: String,
)
@Serializable
data class VolumeWeightedAveragePrice(
var today: String,
var last24Hours: String,
)
@Serializable
data class NumberOfTrades(
var today: String,
var last24Hours: String,
)
@Serializable
data class LowPrice(
var today: String,
var last24Hours: String,
)
@Serializable
data class HighPrice(
var today: String,
var last24Hours: String,
)
@Serializable
data class OpenPrice(
var today: String,
var last24Hours: String,
)
And this is my Payload Parser:
class KrakenApiWebSocketPayload(val json: Json) {
fun getTicker(response:String): Ticker {
val tickerArray : JsonArray = json.decodeFromString(response)
val tickerObject : JsonObject = tickerArray[1].jsonObject
val ask : JsonArray = tickerObject.get("a")!!.jsonArray
val bid : JsonArray = tickerObject.get("b")!!.jsonArray
val close : JsonArray = tickerObject.get("c")!!.jsonArray
val volume : JsonArray = tickerObject.get("h")!!.jsonArray
val volumeWeightedAveragePrice : JsonArray = tickerObject.get("l")!!.jsonArray
val numberOfTrades : JsonArray = tickerObject.get("o")!!.jsonArray
val lowPrice : JsonArray = tickerObject.get("p")!!.jsonArray
val highPrice : JsonArray = tickerObject.get("t")!!.jsonArray
val openPrice : JsonArray = tickerObject.get("v")!!.jsonArray
return Ticker(tickerArray[0].toString(),tickerArray[2].toString(),tickerArray[3].toString(),
TickerData(
Ask(ask[0].toString(),ask[1].toString().toInt(),ask[2].toString()),
Bid(bid[0].toString(),bid[1].toString().toInt(),bid[2].toString()),
Close(close[0].toString(),close[1].toString()),
Volume(volume[0].toString(),volume[1].toString()),
VolumeWeightedAveragePrice(volumeWeightedAveragePrice[0].toString(),volumeWeightedAveragePrice[1].toString()),
NumberOfTrades(numberOfTrades[0].toString(),numberOfTrades[1].toString()),
LowPrice(lowPrice[0].toString(),lowPrice[1].toString()),
HighPrice(highPrice[0].toString(),highPrice[1].toString()),
OpenPrice(openPrice[0].toString(),openPrice[1].toString())
)
)
}
}