Thursday, March 24, 2022

jetpack compose ktor - How to get api data

KtorClient.kt

package com.cfsuman.composenetwork

import android.util.Log
import io.ktor.client.*
import io.ktor.client.features.*
import io.ktor.client.features.json.*
import io.ktor.client.features.json.serializer.*
import io.ktor.client.features.logging.*
import io.ktor.client.request.*
import io.ktor.http.*
import kotlinx.serialization.json.Json

object KtorClient{
    private val json = Json {
        encodeDefaults = true
        ignoreUnknownKeys = true
    }

    val httpClient = HttpClient {
        install(JsonFeature){
            serializer = KotlinxSerializer(json)
        }

        install(Logging){
            logger = object : Logger {
                override fun log(message: String) {
                    Log.d("xapp-ktor", message )
                }
            }
            level = LogLevel.ALL
        }

        install(HttpTimeout){
            socketTimeoutMillis = 15_000
            requestTimeoutMillis = 15_000
            connectTimeoutMillis = 15_000
        }

        defaultRequest {
            contentType(ContentType.Application.Json)
            accept(ContentType.Application.Json)
        }
    }
}
APICaller.kt

package com.cfsuman.composenetwork

import io.ktor.client.request.*
import io.ktor.utils.io.core.*
import kotlinx.serialization.Serializable


suspend fun getUsers(): List<User> {
    return KtorClient.httpClient.use {
        it.get("https://jsonplaceholder.typicode.com/todos")
    }
}

@Serializable
data class User(
    val userId: Int,
    val id: Int,
    val title: String,
    val completed: Boolean
)
MainActivity.kt

package com.cfsuman.composenetwork

import android.os.Bundle
import android.util.Log
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
import com.cfsuman.composenetwork.ui.theme.ComposeNetworkTheme

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            ComposeNetworkTheme {
                MainContent()
            }
        }
    }
}


@Composable
fun MainContent() {
    Log.d("xapp-called","Compose")

    val users = produceState(
        initialValue = listOf<User>(),
        producer = {
            value = getUsers()
            Log.d("xapp-called","Producer")
        }
    )

    LazyColumn(
        Modifier.fillMaxSize(),
        contentPadding = PaddingValues(12.dp),
        verticalArrangement = Arrangement.spacedBy(12.dp)
    ){
        items(users.value){ user->
            Card(
                modifier = Modifier.fillMaxWidth(),
                elevation = 2.dp,
                backgroundColor = if (user.completed)
                    Color(0xFFB6F1B8) else Color.White
            ) {
                Row(
                    Modifier.padding(12.dp),
                    verticalAlignment = Alignment.CenterVertically,
                    horizontalArrangement = Arrangement.spacedBy(12.dp)
                ) {
                    Box(
                        Modifier
                            .clip(CircleShape)
                            .background(Color(0xFF4CAF50))
                            .size(48.dp),
                        contentAlignment = Alignment.Center
                    ) {
                        Text(text = "${user.id}")
                    }
                    Text(text = user.title)
                }
            }
        }
    }
}
build.gradle [project]

buildscript {
    dependencies {
        classpath "org.jetbrains.kotlin:kotlin-serialization:1.6.10"
    }
}
build.gradle [app]

plugins {
    id 'kotlinx-serialization'
}


dependencies {
    implementation 'io.ktor:ktor-client-android:1.6.8'
    implementation 'io.ktor:ktor-client-serialization:1.6.8'
    implementation 'org.jetbrains.kotlinx:kotlinx-serialization-json:1.3.0'
    implementation 'io.ktor:ktor-client-logging-jvm:1.6.8'
}