Študijné materiály

V predošlých lekciách sme používali sealed triedy na reprezentáciu stavov. Teraz si ukážeme, ako ich použiť v kombinácii s HTTP klientom na elegantné spracovanie odpovedí:

import io.ktor.client.*
import io.ktor.client.call.*
import io.ktor.client.engine.cio.*
import io.ktor.client.plugins.contentnegotiation.*
import io.ktor.client.plugins.*
import io.ktor.client.request.*
import io.ktor.http.*
import io.ktor.serialization.kotlinx.json.*
import kotlinx.serialization.Serializable
import kotlinx.coroutines.runBlocking

@Serializable
data class Todo(val id: Int, val title: String, val completed: Boolean)

sealed class NetworkResult {
    data object Loading : NetworkResult()
    data class Success(val data: List<Todo>) : NetworkResult()
    data class Error(val message: String) : NetworkResult()
}

suspend fun fetchTodos(client: HttpClient): NetworkResult {
    return try {
        val response = client.get("https://jsonplaceholder.typicode.com/todos")
        if (response.status == HttpStatusCode.OK) {
            val todos = response.body<List<Todo>>()
            NetworkResult.Success(todos)
        } else {
            NetworkResult.Error("Server vratil: ${response.status}")
        }
    } catch (e: Exception) {
        NetworkResult.Error("Chyba siete: ${e.message}")
    }
}

fun handleResult(result: NetworkResult) {
    when (result) {
        is NetworkResult.Loading -> println("Nacitavam data...")
        is NetworkResult.Success -> {
            println("Nacitaných ${result.data.size} todo:")
            result.data.take(3).forEach { println("  - ${it.title}") }
        }
        is NetworkResult.Error -> println("Chyba: ${result.message}")
    }
}

fun main() = runBlocking {
    val client = HttpClient(CIO) {
        install(ContentNegotiation) { json() }
    }

    val result = fetchTodos(client)
    handleResult(result)

    client.close()
}

Tento vzor (sealed class + when) je veľmi častý v Android vývoji pre spracovanie stavov UI.

Úlohy

Úloha 1

Vytvor sealed triedu výsledku požiadavky so stavmi načítavanie, úspech a chyba.

Úloha 2

Napíš suspend funkciu, ktorá pri úspešnej odpovedi vráti dáta a pri chybe stav chyby.

Úloha 3

Spracuj výsledok úplným when a pri úspechu vypíš počet načítaných objektov.