Por que Kotlin não é apenas para Android?
\n\nSe você ainda acha que Kotlin é apenas um "Java melhorado" para Android, está perdendo o essencial. Em um mundo onde todos querem escrever um único código e executá-lo em qualquer lugar, o Kotlin Multiplatform (KMP) está se tornando um verdadeiro "assassino" de frameworks como Flutter e React Native. Mas, ao contrário deles, o Kotlin não obriga você a abandonar a UI nativa ou aprender JavaScript.
\n\nImagine: você escreve a lógica de negócios, requisições de rede e trabalho com banco de dados uma única vez em Kotlin. E então usa esse código no Android, iOS, na web e até no servidor (Ktor). Parece fantasia? Bem-vindo à realidade do desenvolvimento multiplataforma com Kotlin.
\n\nNeste artigo, não vamos apenas falar sobre teoria. Vamos mostrar exemplos reais de código, comparar o KMP com concorrentes e dar a você um plano passo a passo para começar hoje mesmo.
\n\nO que é Kotlin Multiplatform (KMP) e para que serve?
\n\nKMP não é um framework. É uma tecnologia de compilação embutida na linguagem Kotlin. Ela permite compilar código comum (common code) para diferentes plataformas:
\n\n- \n
- Android — bytecode JVM (como de costume). \n
- iOS — binário nativo (via LLVM). \n
- JavaScript/Web — código JS para o navegador. \n
- Native (Linux, Windows, macOS) — via Kotlin/Native. \n
O principal diferencial: você escreve expect/actual — declara a API esperada no código comum e a implementa separadamente para cada plataforma. Todo o resto é compartilhado.
\n\nExemplo 1: Módulo comum para requisições de rede
\n\nVamos escrever um cliente HTTP simples que funcionará no Android e iOS. Para isso, usaremos o Ktor — um cliente escrito em Kotlin.
\n\nPasso 1: Estrutura do projeto (Gradle)
\n\nNo arquivo build.gradle.kts do seu módulo comum:
plugins {\n kotlin("multiplatform")\n id("io.ktor.plugin") version "2.3.7"\n}\n\nkotlin {\n androidTarget()\n iosX64()\n iosArm64()\n iosSimulatorArm64()\n\n sourceSets {\n val commonMain by getting {\n dependencies {\n implementation("io.ktor:ktor-client-core:2.3.7")\n implementation("io.ktor:ktor-client-content-negotiation:2.3.7")\n implementation("io.ktor:ktor-serialization-kotlinx-json:2.3.7")\n }\n }\n val androidMain by getting {\n dependencies {\n implementation("io.ktor:ktor-client-android:2.3.7")\n }\n }\n val iosMain by creating {\n dependsOn(commonMain)\n dependencies {\n implementation("io.ktor:ktor-client-darwin:2.3.7")\n }\n }\n }\n}\n\nPasso 2: Código comum (commonMain)
\n\nCriaremos uma data class e um cliente de API:
\n\n// commonMain/kotlin/com/example/User.kt\nimport kotlinx.serialization.Serializable\n\n@Serializable\ndata class User(\n val id: Int,\n val name: String,\n val email: String\n)\n\n// commonMain/kotlin/com/example/ApiClient.kt\nimport io.ktor.client.*\nimport io.ktor.client.call.*\nimport io.ktor.client.plugins.contentnegotiation.*\nimport io.ktor.client.request.*\nimport io.ktor.serialization.kotlinx.json.*\n\nclass ApiClient {\n private val client = HttpClient {\n install(ContentNegotiation) {\n json()\n }\n }\n\n suspend fun fetchUser(id: Int): User {\n return client.get("https://jsonplaceholder.typicode.com/users/$id").body()\n }\n}\n\nViu? Nenhum if, nenhuma verificação de plataforma. Apenas Kotlin puro.
\n\nExemplo 2: Expect/Actual para trabalhar com SharedPreferences
\n\nSuponha que precisamos salvar um token. No Android — SharedPreferences, no iOS — UserDefaults. Mostramos a mágica do KMP:
\n\nCódigo comum (commonMain):
\n\n// commonMai