Estrutura de projeto KMP: commonMain, androidMain, iosMain
Entenda a hierarquia dos conjuntos de código-fonte e como o código é compartilhado entre os alvos.
Estrutura de projeto KMP: commonMain, androidMain, iosMain é uma aula grátis de Kotlin Academy no CoddyKit. Esta é a aula 1 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de Kotlin Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de Kotlin Academy inclui 4 aulas no total.
O que é KMP?
O Kotlin Multiplatform (KMP) permite escrever código Kotlin compartilhado que compila para JVM, Android, iOS (por meio de Kotlin/Native) e JS. O código específico da plataforma fica em conjuntos de origem separados.
// Typical KMP module structure:
// shared/
// src/
// commonMain/kotlin/ <- shared code
// androidMain/kotlin/ <- Android-only
// iosMain/kotlin/ <- iOS-only
// commonTest/kotlin/ <- shared tests
fun main() { println("KMP: one codebase, many targets") }Hierarquia de conjuntos de origem
Os conjuntos de origem formam uma hierarquia. commonMain é a raiz; androidMain e iosMain dependem dele. O código em commonMain fica visível para todos os destinos.
// build.gradle.kts (Kotlin DSL)
kotlin {
androidTarget()
iosX64()
iosArm64()
iosSimulatorArm64()
sourceSets {
val commonMain by getting {
dependencies { /* shared deps */ }
}
val androidMain by getting
val iosMain by getting
}
}commonMain: lógica compartilhada
Coloque a lógica de negócio, os modelos de domínio, os repositórios e os casos de uso em commonMain. Esse código compila para todos os destinos.
// commonMain/kotlin/com/example/domain/User.kt
data class User(val id: String, val name: String, val email: String)
// commonMain/kotlin/com/example/repository/UserRepository.kt
interface UserRepository {
suspend fun getUser(id: String): User?
suspend fun saveUser(user: User)
}androidMain: específico do Android
androidMain pode usar classes do SDK do Android. Usos comuns: implementações específicas do Android para declarações expect/actual.
// androidMain/kotlin/com/example/platform/PlatformLogger.kt
import android.util.Log
class AndroidLogger : Logger {
override fun log(msg: String) = Log.d("App", msg)
}
// androidMain/kotlin/com/example/di/PlatformModule.kt
// Koin or Hilt module that binds AndroidLogger to LoggeriosMain: específico do iOS
iosMain tem acesso aos frameworks da Apple por meio da interoperabilidade do Kotlin/Native. Use-o para as implementações iOS das APIs expect/actual.
// iosMain/kotlin/com/example/platform/PlatformLogger.kt
import platform.Foundation.NSLog
class IosLogger : Logger {
override fun log(msg: String) = NSLog(msg)
}
// iOS uses Kotlin/Native runtime; no JVM hereConfiguração do Gradle para destinos iOS
Para iOS, normalmente você declara três destinos: x64 (simulador em processadores Intel), arm64 (dispositivo) e simulatorArm64 (simulador em Apple Silicon).
// build.gradle.kts
kotlin {
iosX64()
iosArm64()
iosSimulatorArm64()
sourceSets {
val iosMain by creating {
dependsOn(commonMain.get())
}
val iosX64Main by getting { dependsOn(iosMain) }
val iosArm64Main by getting { dependsOn(iosMain) }
val iosSimulatorArm64Main by getting { dependsOn(iosMain) }
}
}Dependências compartilhadas em commonMain
Adicione as dependências compartilhadas (Ktor, SQLDelight, kotlinx.serialization, Koin) a commonMain. Os drivers específicos da plataforma ficam nos conjuntos de origem da plataforma.
// commonMain dependencies example:
// implementation("io.ktor:ktor-client-core:2.3.0")
// implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.5.1")
// implementation("io.insert-koin:koin-core:3.4.0")
// androidMain:
// implementation("io.ktor:ktor-client-okhttp:2.3.0")
// iosMain:
// implementation("io.ktor:ktor-client-darwin:2.3.0")commonTest: testes compartilhados
Os testes em commonTest são executados em todos os destinos. Use a biblioteca de testes do Kotlin e escreva testes de unidade independentes do destino para a lógica de negócio compartilhada.
// commonTest/kotlin/UserRepositoryTest.kt
import kotlin.test.Test
import kotlin.test.assertEquals
class UserRepositoryTest {
@Test
fun testUserCreation() {
val user = User("1", "Alice", "alice@example.com")
assertEquals("Alice", user.name)
}
}Conjuntos de origem intermediários
Você pode criar conjuntos de origem intermediários compartilhados entre um subconjunto de destinos, por exemplo, nativeMain para todos os destinos nativos ou appleMain para iOS + macOS.
// Create appleMain shared between iOS and macOS:
sourceSets {
val appleMain by creating { dependsOn(commonMain.get()) }
val iosMain by getting { dependsOn(appleMain) }
val macosMain by getting { dependsOn(appleMain) }
}Estrutura de arquivos do projeto
Uma árvore de diretórios típica de um módulo compartilhado KMP que separa claramente as responsabilidades.
// shared/
// build.gradle.kts
// src/
// commonMain/kotlin/
// domain/ User.kt, Post.kt
// repository/ UserRepository.kt
// usecase/ GetUserUseCase.kt
// androidMain/kotlin/
// repository/ RoomUserRepository.kt
// iosMain/kotlin/
// repository/ CoreDataUserRepository.kt
// commonTest/kotlin/ GetUserUseCaseTest.ktIntegração com CocoaPods / SPM
O plug-in do Gradle para KMP gera um XCFramework (ou um pod do CocoaPods) que você adiciona ao projeto do Xcode, expondo o código Kotlin compartilhado como um framework nativo.
// build.gradle.kts for CocoaPods:
kotlin {
cocoapods {
name = "Shared"
version = "1.0"
ios.deploymentTarget = "14.0"
framework { baseName = "Shared" }
}
}
// Run: ./gradlew :shared:podPublishReleaseXCFrameworkVerificação rápida
Onde a lógica de negócio compartilhada (modelos de domínio e casos de uso) deve ser colocada em um projeto KMP?
Recapitulação
commonMain contém a lógica compartilhada (domínio, repositórios e casos de uso). androidMain/iosMain contêm as implementações da plataforma. commonTest executa testes em todos os destinos. As dependências são divididas: APIs compartilhadas em commonMain e drivers da plataforma nos conjuntos de origem específicos da plataforma.
Perguntas Frequentes
A aula “Estrutura de projeto KMP: commonMain, androidMain, iosMain” é grátis?
Sim — o texto completo de “Estrutura de projeto KMP: commonMain, androidMain, iosMain” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de Kotlin Academy, atualize para CoddyKit PRO. O curso de Kotlin Academy inclui 4 aulas no total.
O que vou aprender em “Estrutura de projeto KMP: commonMain, androidMain, iosMain”?
Entenda a hierarquia dos conjuntos de código-fonte e como o código é compartilhado entre os alvos. Você pratica Kotlin Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.
Preciso ter experiência prévia para começar Kotlin Academy?
Nenhuma experiência prévia é necessária. Kotlin Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 1 de 4.
Quanto tempo leva a aula “Estrutura de projeto KMP: commonMain, androidMain, iosMain”?
A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.
Posso escrever e executar código nesta aula de Kotlin Academy?
Sim. Cada aula de Kotlin Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.
Todas as aulas deste curso
- Estrutura de projeto KMP: commonMain, androidMain, iosMain
- Mecanismo expect/actual para APIs de plataforma
- Compartilhando camadas de repositório e casos de uso
- Injeção de dependências em KMP com Koin