By placing the JSON file locally in src/main/assets
folder you can easily access its content to deserialize it (I used .decodeFromString() method here). However, it's not clear how to deserialize a remote JSON data in Jetpack Compose app.
For example, a data located at the address https://api.opendota.com/api/heroStats
or at the address https://restcountries.com/v3.1/all
.
Here's a code with a local JSON parsing:
@Serializable
data class Root(val tenants: List<Tenant>)
@Serializable
data class Tenant(val name: String, val room: Int)
@Composable
fun DecodedText() {
var text: String by remember { mutableStateOf("") }
val context = LocalContext.current
LaunchedEffect(Unit) {
val json = readJsonFromAssets(context = context, fileName = "sample.json")
val decoded = Json.decodeFromString<Root>(json).tenants
for (i in decoded.indices) {
text += decoded[i].name + " – "
text += decoded[i].room.toString() + "\n"
}
}
Text(
text = text,
fontWeight = FontWeight.Black,
fontSize = 22.sp,
modifier = Modifier.padding(50.dp)
)
}
fun readJsonFromAssets(context: Context, fileName: String): String {
return context.assets.open(fileName).bufferedReader().use { it.readText() }
}
I'd like to know how to do this using the kotlin serialization plugin. Any help appreciated.
After carefully studying this issue, I came to the following solution. I tried to parse JSON data using both web addresses, both examples are decoded fine, for my answer I've chosen the second address. Here's my code:
typealias Countries = List<Country>
private val jsonPty = Json {
ignoreUnknownKeys = true
}
@Serializable
data class Country(
val name: Names
)
@Serializable
data class Names(
val common: String,
val official: String
)
@ExperimentalSerializationApi
@Composable
fun RemoteDecodedText() {
val url = URL("https://restcountries.com/v3.1/all")
var json: String by remember { mutableStateOf("") }
var parsedJson: String by remember { mutableStateOf("") }
val scope = CoroutineScope(Dispatchers.Default)
LaunchedEffect(Unit) {
scope.launch {
json = url.openStream().use {
it.readAllBytes().decodeToString()
}
parsedJson = jsonPty.decodeFromString<Countries>(json)[64].name.official
}
}
Text(
text = "Location: $parsedJson",
fontSize = 20.sp,
fontWeight = FontWeight.Black,
modifier = Modifier.padding(60.dp)
)
}
Result (index=64) :
// Location: Kingdom of Morocco