---
title: "Kotlin Multiplatform Mobile (KMM): Guia Completo em Português | Kotlin Brasil"
url: "https://kotlin.dev.br/guias/guia-kotlin-multiplatform-mobile/"
markdown_url: "https://kotlin.dev.br/guias/guia-kotlin-multiplatform-mobile.MD"
description: "Aprenda Kotlin Multiplatform Mobile para compartilhar código entre Android e iOS. Guia completo com setup, arquitetura e exemplos práticos."
date: "2025-07-09"
author: "Karina Melo"
---

# Kotlin Multiplatform Mobile (KMM): Guia Completo em Português | Kotlin Brasil

Aprenda Kotlin Multiplatform Mobile para compartilhar código entre Android e iOS. Guia completo com setup, arquitetura e exemplos práticos.


Kotlin Multiplatform Mobile, agora oficialmente chamado apenas de Kotlin Multiplatform (KMP), permite compartilhar lógica de negócio entre Android e iOS usando Kotlin. Diferente de frameworks cross-platform que compartilham também a UI, como Flutter ou React Native, o KMP adota uma abordagem pragmatica: você compartilha o código que faz sentido compartilhar -- lógica de negócio, acesso a dados, validacoes -- e mantém a interface nativa de cada plataforma. Neste guia, vamos configurar um projeto KMP do zero, entender a arquitetura, implementar modulos compartilhados e explorar as melhores práticas para projetos reais.

## Por Que Kotlin Multiplatform

A proposta do KMP e diferente de outras solucoes cross-platform. Enquanto Flutter substitui a UI nativa por seu próprio engine de renderizacao e React Native usa uma ponte entre JavaScript e componentes nativos, o KMP compila diretamente para JVM no Android e para código nativo via Kotlin/Native no iOS. Isso significa performance nativa em ambas as plataformas sem camadas de abstração adicionais.

As vantagens incluem compartilhamento gradual de código, integração total com projetos existentes é a possibilidade de manter equipes Android e iOS trabalhando com suas ferramentas nativas para a UI.

## Configurando o Projeto

O Kotlin Multiplatform Wizard (disponivel em kmp.jetbrains.com) gera a estrutura inicial. Um projeto KMP tipico possui tres modulos principais:

```kotlin
// settings.gradle.kts
rootProject.name = "MeuAppKMP"
include(":androidApp")
include(":iosApp")
include(":shared")

// shared/build.gradle.kts
plugins {
    kotlin("multiplatform")
    id("com.android.library")
    kotlin("plugin.serialization")
}

kotlin {
    androidTarget {
        compilations.all {
            kotlinOptions {
                jvmTarget = "17"
            }
        }
    }

    listOf(
        iosX64(),
        iosArm64(),
        iosSimulatorArm64()
    ).forEach {
        it.binaries.framework {
            baseName = "shared"
            isStatic = true
        }
    }

    sourceSets {
        val commonMain by getting {
            dependencies {
                implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3")
                implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.2")
                implementation("io.ktor:ktor-client-core:2.3.7")
                implementation("io.ktor:ktor-client-content-negotiation:2.3.7")
                implementation("io.ktor:ktor-serialization-kotlinx-json:2.3.7")
            }
        }
        val androidMain by getting {
            dependencies {
                implementation("io.ktor:ktor-client-android:2.3.7")
            }
        }
        val iosMain by getting {
            dependencies {
                implementation("io.ktor:ktor-client-darwin:2.3.7")
            }
        }
    }
}
```

## Estrutura de Source Sets

O KMP utiliza source sets para organizar código compartilhado e código específico de cada plataforma:

```kotlin
// shared/src/commonMain/kotlin/
// Código Kotlin puro, compartilhado entre todas as plataformas

// shared/src/androidMain/kotlin/
// Código especifico do Android (pode usar APIs do Android SDK)

// shared/src/iosMain/kotlin/
// Código especifico do iOS (pode usar APIs do iOS via interop)
```

## Expect e Actual

O mecanismo `expect`/`actual` permite declarar APIs no código comum e implementa-las em cada plataforma:

```kotlin
// commonMain - Declaracao
expect class PlatformInfo() {
    val nome: String
    val versao: String
}

// androidMain - Implementacao Android
actual class PlatformInfo actual constructor() {
    actual val nome: String = "Android"
    actual val versao: String = "${android.os.Build.VERSION.SDK_INT}"
}

// iosMain - Implementacao iOS
actual class PlatformInfo actual constructor() {
    actual val nome: String = UIDevice.currentDevice.systemName()
    actual val versao: String = UIDevice.currentDevice.systemVersion
}
```

Outro exemplo prático com armazenamento local:

```kotlin
// commonMain
expect class KeyValueStorage {
    fun getString(key: String, default: String = ""): String
    fun putString(key: String, value: String)
    fun clear()
}

// androidMain
actual class KeyValueStorage(private val context: Context) {
    private val prefs = context.getSharedPreferences(
        "app_prefs", Context.MODE_PRIVATE
    )

    actual fun getString(key: String, default: String): String {
        return prefs.getString(key, default) ?: default
    }

    actual fun putString(key: String, value: String) {
        prefs.edit().putString(key, value).apply()
    }

    actual fun clear() {
        prefs.edit().clear().apply()
    }
}

// iosMain
actual class KeyValueStorage {
    private val defaults = NSUserDefaults.standardUserDefaults

    actual fun getString(key: String, default: String): String {
        return defaults.stringForKey(key) ?: default
    }

    actual fun putString(key: String, value: String) {
        defaults.setObject(value, forKey = key)
    }

    actual fun clear() {
        val dicionario = defaults.dictionaryRepresentation()
        for (key in dicionario.keys) {
            defaults.removeObjectForKey(key as String)
        }
    }
}
```

## Networking Compartilhado com Ktor

O Ktor Client funciona em ambas as plataformas, permitindo compartilhar toda a camada de rede:

```kotlin
// commonMain
class ApiClient {
    private val httpClient = HttpClient {
        install(ContentNegotiation) {
            json(Json {
                ignoreUnknownKeys = true
                prettyPrint = true
            })
        }
    }

    suspend fun buscarProdutos(): List<ProdutoDto> {
        return httpClient.get("https://api.exemplo.com/produtos")
            .body()
    }

    suspend fun buscarProduto(id: Long): ProdutoDto {
        return httpClient.get("https://api.exemplo.com/produtos/$id")
            .body()
    }
}

@Serializable
data class ProdutoDto(
    val id: Long,
    val nome: String,
    val preco: Double,
    val descricao: String
)
```

## Repository Compartilhado

O padrão Repository funciona perfeitamente no modulo compartilhado:

```kotlin
// commonMain
class ProdutoRepository(
    private val apiClient: ApiClient
) {
    private val _produtos = MutableStateFlow<List<ProdutoDto>>(emptyList())
    val produtos: StateFlow<List<ProdutoDto>> = _produtos.asStateFlow()

    suspend fun carregarProdutos(): Result<List<ProdutoDto>> {
        return try {
            val resultado = apiClient.buscarProdutos()
            _produtos.value = resultado
            Result.success(resultado)
        } catch (e: Exception) {
            Result.failure(e)
        }
    }
}
```

## Integração com o App Android

No Android, o modulo shared e consumido como uma dependência normal:

```kotlin
// androidApp/build.gradle.kts
dependencies {
    implementation(project(":shared"))
}

// Uso no Android
class ProdutoViewModel(
    private val repository: ProdutoRepository
) : ViewModel() {
    val produtos = repository.produtos
        .stateIn(viewModelScope, SharingStarted.Lazily, emptyList())
}
```

## Integração com o App iOS

No iOS, o framework gerado e importado no Swift:

```kotlin
// No Xcode / Swift
import shared

class ProdutoViewModel: ObservableObject {
    @Published var produtos: [ProdutoDto] = []

    private let repository = ProdutoRepository(
        apiClient: ApiClient()
    )

    func carregarProdutos() {
        Task {
            let resultado = try await repository.carregarProdutos()
            // Atualizar estado
        }
    }
}
```

## Boas Práticas com Kotlin Multiplatform

- **Compartilhe lógica, não UI**: mantenha a interface nativa para melhor experiência do usuário em cada plataforma.
- **Use interfaces no código comum**: defina contratos com interfaces e implemente com `expect`/`actual` apenas quando necessário.
- **Prefira bibliotecas multiplatform**: Ktor, kotlinx-serialization, SQLDelight e Koin possuem suporte KMP nativo.
- **Teste no commonTest**: escreva testes unitarios no source set compartilhado para maxima cobertura entre plataformas.
- **Adoção incremental**: comece compartilhando uma camada pequena (modelos de dados, por exemplo) e expanda gradualmente.
- **Mantenha o modulo shared leve**: evite dependências pesadas que aumentem o tamanho do framework iOS.

## Erros Comuns e Armadilhas

- **Congelar objetos no Kotlin/Native**: versões mais antigas exigiam que objetos compartilhados entre threads fossem "frozen". A partir do novo gerenciador de memória, isso não e mais necessário, mas bibliotecas antigas podem ainda ter essa restricao.
- **Coroutines no iOS**: o Swift não entende `suspend` nativamente. Use wrappers como SKIE ou KMP-NativeCoroutines para expor funções suspensas como Swift async/await.
- **Build times longos**: projetos KMP podem ter builds mais demorados. Configure caching adequado e builds incrementais.
- **Ignorar diferencias de plataforma**: nem toda funcionalidade pode ou deve ser compartilhada. Permissoes, notificacoes push e acesso a sensores geralmente são melhor tratados nativamente.
- **Dependências transitivas**: bibliotecas Java puras não funcionam no iOS. Certifique-se de que todas as dependências do commonMain sejam multiplatform.

## Conclusão e Próximos Passos

O Kotlin Multiplatform oferece uma abordagem equilibrada para o desenvolvimento multiplataforma, combinando compartilhamento de código com interfaces nativas. A tecnologia amadureceu significativamente e já e usada em producao por empresas como Netflix, Philips e Cash App. Para aprofundar seus conhecimentos, explore o Compose Multiplatform para compartilhar também a UI, estude SQLDelight para persistencia multiplatform e consulte os demais guias sobre arquitetura e testes aqui no Kotlin Brasil. Se multiplataforma é seu foco, vale conhecer também <a href="https://python.dev.br/" target="_blank" rel="noopener" onclick="umami.track('portfolio-site-click', { destination: 'python.dev.br' })">Python para scripts e automação cross-platform</a> e <a href="https://rustlang.com.br/" target="_blank" rel="noopener" onclick="umami.track('portfolio-site-click', { destination: 'rustlang.com.br' })">Rust para módulos nativos de alta performance</a>.
