Data Serialization and Networking Made Simple
Efficient data handling and networking are the backbone of modern cross-platform apps. In Kotlin Multiplatform (KMP), tools like kotlinx.serialization and Ktor Client streamline these tasks, enabling seamless data exchange across Android, iOS, and web. This chapter dives into serialization, HTTP requests, and asynchronous operations in KMP—all while keeping your codebase clean and platform-agnostic.
Kotlin’s kotlinx.serialization
library simplifies converting objects to formats like JSON, ProtoBuf, or XML.
Add these dependencies to build.gradle.kts
:
// Shared module
plugins {
kotlin("plugin.serialization") version "1.9.20"
}
dependencies {
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.0")
}
import kotlinx.serialization.Serializable
@Serializable
data class User(val id: Int, val name: String, val email: String)
val user = User(1, "Alex", "alex@example.com") val json = Json.encodeToString(user) // Output: {"id":1,"name":"Alex","email":"alex@example.com"}
val jsonData = """{"id":1,"name":"Alex","email":"alex@example.com"}""" val userObj = Json.decodeFromString<User>(jsonData)
Handling Missing Fields:
val json = Json { ignoreUnknownKeys = true } // Skips unknown keys during deserialization
Ktor is a multiplatform HTTP client for handling API requests.
Add platform-specific dependencies:
// Shared module
dependencies {
implementation("io.ktor:ktor-client-core:2.3.6")
implementation("io.ktor:ktor-client-content-negotiation:2.3.6")
implementation("io.ktor:ktor-serialization-kotlinx-json:2.3.6")
}
// Platform modules
androidMain {
implementation("io.ktor:ktor-client-okhttp:2.3.6")
}
iosMain {
implementation("io.ktor:ktor-client-darwin:2.3.6")
}
jsMain {
implementation("io.ktor:ktor-client-js:2.3.6")
}
import io.ktor.client.*
import io.ktor.client.plugins.contentnegotiation.*
val httpClient = HttpClient {
install(ContentNegotiation) {
json(Json { ignoreUnknownKeys = true })
}
}
suspend fun fetchUser(): User {
return httpClient.get("https://api.example.com/user/1").body()
}
// Usage
suspend fun printUser() {
val user = fetchUser()
println(user) // User(id=1, name=Alex, email=alex@example.com)
}
suspend fun fetchUserSafe(): User? {
return try {
httpClient.get("https://api.example.com/user/1").body()
} catch (e: ClientRequestException) {
println("Error: ${e.response.status}")
null
} catch (e: ServerResponseException) {
println("Server error: ${e.response.status}")
null
}
}
KMP supports multiple formats via kotlinx.serialization
:
Format | Use Case | Dependency |
---|---|---|
JSON | Web APIs | kotlinx-serialization-json |
ProtoBuf | High-performance systems | kotlinx-serialization-protobuf |
CBOR | Compact binary data | kotlinx-serialization-cbor |
// Add dependency
implementation("org.jetbrains.kotlinx:kotlinx-serialization-protobuf:1.6.0")
// Serialize
val data = SensorData(1675038210, 24.5)
val bytes: ByteArray = ProtoBuf.encodeToByteArray(data)
// Deserialize
val decodedData = ProtoBuf.decodeFromByteArray<SensorData>(bytes)
Kotlin Coroutines handle async tasks without blocking the main thread.
suspend fun fetchMultipleUsers(): List<User> = coroutineScope {
val user1 = async { fetchUser() }
val user2 = async { fetchUser() }
listOf(user1.await(), user2.await())
}
Platform | Dispatcher |
---|---|
Android | Dispatchers.Main |
iOS | MainScope().launch |
Shared Code | Dispatchers.Default |
Best Practices:
Dispatchers.IO
for network calls.try-catch
.kotlinx.serialization
for JSON/ProtoBuf conversions.Introduction: Transform Your Cross-Platform Development with Material Design 3 Are you ready to revolutionize your… Read More
Jetpack Compose 1.8 rolls out handy features like Autofill integration, slick Text enhancements including auto-sizing… Read More
Reified Keyword in Kotlin: Simplify Your Generic Functions Kotlin's reified keyword lets your generic functions know the… Read More
Android Studio Cloud: Ditch the Setup, Code Anywhere (Seriously!) Alright, fellow Android devs, gather 'round… Read More