Kotlin Multiplatform di 2026: Berbagi Kode Android dan iOS

Cara Kotlin Multiplatform berbagi logika bisnis antara Android dan iOS pada 2026, lengkap dengan setup Gradle, expect/actual, jaringan Ktor, UI Compose Multiplatform, dan pertanyaan wawancara KMP.

Kotlin Multiplatform 2026 berbagi kode antara aplikasi Android dan iOS

Kotlin Multiplatform (KMP) memungkinkan satu basis kode Kotlin menjalankan logika bisnis aplikasi Android sekaligus iOS, sementara setiap platform tetap mempertahankan UI native, performa, dan akses penuh ke SDK-nya. Pada 2026 KMP bukan lagi eksperimen: teknologi ini sudah stabil, didukung resmi oleh Google, dan berjalan di produksi pada Netflix, McDonald's, Forbes, serta Cash App. Pembahasan mendalam ini menguraikan cara berbagi kode benar-benar bekerja, cara mengonfigurasi modul bersama, dan kompromi yang perlu dipahami sebelum menghadapi wawancara KMP.

Apa yang sebenarnya dibagikan KMP

Kotlin Multiplatform berbagi logika yang sudah dikompilasi, bukan sebuah runtime. Kotlin common dikompilasi menjadi bytecode JVM untuk Android dan menjadi biner native (melalui LLVM) untuk iOS. Tidak ada jembatan JavaScript, tidak ada webview tertanam, dan tidak ada lapisan refleksi, sehingga kode bersama berjalan pada kecepatan native di kedua platform.

Bagaimana Kotlin Multiplatform Berbagi Kode Tanpa Mengorbankan Performa Native

Mekanisme intinya adalah hierarki source set. commonMain menampung Kotlin yang agnostik terhadap platform: jaringan, serialisasi, aturan bisnis, dan view model. Source set platform seperti androidMain dan iosMain menampung kode yang menyentuh API platform. Kompiler menghasilkan artefak JVM dari commonMain plus androidMain untuk Android, dan sebuah framework native dari commonMain plus iosMain untuk iOS.

Kotlin Multiplatform pada 2026 mengutamakan berbagi hal yang benar-benar diuntungkan oleh satu sumber kebenaran: model, klien API, caching, dan validasi. UI dapat dibagikan dengan Compose Multiplatform atau dibiarkan sepenuhnya native dengan SwiftUI, layar demi layar. Model "bagikan logika, pilih UI" inilah yang membuat tim mengadopsi KMP tanpa menulis ulang aplikasi yang sudah ada.

Kotlin Multiplatform adalah teknologi Kotlin yang mengompilasi satu modul bersama ke banyak target (Android di JVM, iOS sebagai native, ditambah desktop dan web) sehingga logika bisnis ditulis sekali sementara setiap platform mempertahankan UI native dan akses penuh ke SDK. Google kini mendukungnya sebagai opsi kelas satu, dengan pustaka Jetpack seperti Room, DataStore, ViewModel, dan Paging yang menyediakan artefak KMP.

Menentukan apa yang termasuk dalam modul bersama adalah keputusan arsitektur paling penting dalam sebuah proyek KMP. Tabel di bawah mencerminkan cara sebagian besar tim produksi menarik garis pada 2026: semua yang berada di bawah lapisan presentasi adalah kandidat kuat untuk dibagikan, sementara apa pun yang menyentuh konvensi UX platform biasanya tetap native.

| Lapisan | Bagikan di commonMain? | Alasan | |-------|---------------------|--------| | Model data dan DTO | Ya | Kontrak API identik di kedua platform | | Jaringan dan caching | Ya | Satu tumpukan HTTP, satu permukaan bug | | Aturan bisnis dan validasi | Ya | Domain tidak berbeda per OS | | View model dan state | Biasanya | Compose dan SwiftUI sama-sama memakai state bersama | | Rendering UI | Opsional | Dibagikan dengan Compose, atau native per layar | | API platform (kamera, biometrik) | Tidak | Ekspos melalui expect/actual sebagai gantinya |

Manfaatnya meningkat sesuai seberapa banyak bagian bawah tabel tersebut yang dimiliki sebuah aplikasi. Produk padat data dengan UI tipis berbagi paling banyak; aplikasi yang sangat khusus dan digerakkan animasi berbagi paling sedikit. Tidak ada satu pun ekstrem yang salah, itulah alasan KMP cocok untuk adopsi bertahap ketimbang penulisan ulang total.

Mengonfigurasi Modul Bersama di Gradle

Sebuah modul KMP mendeklarasikan target dan source set-nya dalam Kotlin DSL. Berkas build.gradle.kts berikut menyiapkan Android dan tiga arsitektur iOS (perangkat fisik, simulator Intel, simulator Apple Silicon) serta mengekspos keluaran iOS sebagai framework bernama Shared.

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

kotlin {
    // Android target compiles commonMain + androidMain to JVM bytecode
    androidTarget()

    // Three iOS targets: device, Intel sim, Apple Silicon sim
    listOf(iosArm64(), iosX64(), iosSimulatorArm64()).forEach { target ->
        target.binaries.framework {
            baseName = "Shared"   // becomes "import Shared" in Swift
            isStatic = true
        }
    }

    sourceSets {
        commonMain.dependencies {
            implementation("io.ktor:ktor-client-core:3.3.0")
            implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.9.0")
            implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.2")
        }
        androidMain.dependencies {
            implementation("io.ktor:ktor-client-okhttp:3.3.0")
        }
        iosMain.dependencies {
            implementation("io.ktor:ktor-client-darwin:3.3.0")
        }
    }
}

Setiap target menarik engine Ktor spesifik platform (okhttp di Android, darwin di iOS) sementara kode bersama hanya bergantung pada API umum ktor-client-core. Kumpulan opsi lengkapnya tersedia di dokumentasi Kotlin Multiplatform.

Sebagian logika tidak dapat berada di commonMain karena membutuhkan API platform. Mekanisme expect/actual mendeklarasikan bentuknya di kode common dan menyediakan implementasi konkret per target, diselesaikan saat kompilasi tanpa biaya runtime.

commonMain/kotlin/Platform.ktkotlin
// commonMain declares what it needs but cannot implement here
expect class Platform() {
    val name: String
    val osVersion: String
}

// Shared logic can now depend on Platform freely
fun analyticsUserAgent(): String {
    val platform = Platform()
    return "SharpSkill/" + platform.name + " " + platform.osVersion
}

Implementasi Android membaca dari kelas Build, sedangkan implementasi iOS membaca dari UIDevice. Keduanya memenuhi kontrak yang sama, sehingga commonMain tidak pernah tahu sedang berbicara dengan yang mana.

androidMain/kotlin/Platform.ktkotlin
import android.os.Build

// actual supplies the Android-specific implementation
actual class Platform actual constructor() {
    actual val name: String = "Android"
    actual val osVersion: String = Build.VERSION.RELEASE
}
iosMain/kotlin/Platform.ktkotlin
import platform.UIKit.UIDevice

// actual uses UIKit directly, no Objective-C bridging code required
actual class Platform actual constructor() {
    actual val name: String = "iOS"
    actual val osVersion: String = UIDevice.currentDevice.systemVersion
}

Kotlin/Native menyertakan binding bertipe untuk seluruh SDK iOS, sehingga UIDevice, NSUserDefaults, dan tipe Foundation dapat dipanggil dari Kotlin tanpa kode perekat yang ditulis tangan.

Berbagi Logika Jaringan dan Serialisasi

Jaringan adalah kode dengan nilai tertinggi untuk dibagikan karena kontrak API identik di kedua platform. Satu klien Ktor ditambah kotlinx.serialization menggantikan dua implementasi paralel. Fungsi suspend mengandalkan Kotlin coroutines, yang memetakan dengan rapi ke async/await di kedua sisi.

commonMain/kotlin/data/InterviewRepository.ktkotlin
import io.ktor.client.HttpClient
import io.ktor.client.call.body
import io.ktor.client.plugins.contentnegotiation.ContentNegotiation
import io.ktor.client.request.get
import io.ktor.serialization.kotlinx.json.json
import kotlinx.serialization.Serializable

// One serializable model, zero duplication across platforms
@Serializable
data class Question(val id: String, val prompt: String, val difficulty: String)

// One HttpClient, one JSON parser, one repository for both apps
class InterviewRepository {
    private val client = HttpClient {
        install(ContentNegotiation) { json() }
    }

    suspend fun fetchQuestions(tech: String): List<Question> =
        client.get("https://api.sharpskill.dev/questions/" + tech).body()
}

Repository ini, logika retry-nya, dan model datanya ditulis sekali. Bug yang diperbaiki di parser langsung diperbaiki di Android dan iOS secara bersamaan, dan di situlah KMP membayar kembali biaya penyiapannya. Pola yang sama meluas ke basis data bersama dengan SQLDelight, penyimpanan key-value bersama, serta dependency injection bersama dengan Koin, sehingga seluruh lapisan data dapat berada di commonMain di balik antarmuka yang menjadi sandaran UI.

Kesalahan umum adalah mencoba berbagi terlalu banyak terlalu dini. Jalur pragmatisnya adalah memulai dari satu repository, membuktikan build dan pipeline CI di kedua platform, lalu memindahkan fitur satu per satu seiring bertambahnya kepercayaan diri.

Siap menguasai wawancara Android Anda?

Berlatih dengan simulator interaktif, flashcards, dan tes teknis kami.

Membangun UI Bersama Dengan Compose Multiplatform

Compose Multiplatform mencapai status stabil di iOS pada Mei 2025 (versi 1.8.0) dan mencapai 1.11.0 pada pertengahan 2026 dengan input teks native dan rendering konkuren aktif secara default. Sebuah @Composable di commonMain dirender di kedua platform, dan view model bersama berpadu secara alami dengan arsitektur MVVM atau MVI.

commonMain/kotlin/ui/QuestionList.ktkotlin
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material3.Card
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import androidx.compose.foundation.layout.padding

// This list renders identically on Android and iOS
@Composable
fun QuestionList(questions: List<Question>) {
    LazyColumn {
        items(questions) { question ->
            Card(modifier = Modifier.padding(8.dp)) {
                Text(text = question.prompt, modifier = Modifier.padding(16.dp))
            }
        }
    }
}

Berbagi UI bersifat opsional dan per layar. Sebuah tim dapat membagikan seluruh antarmuka dengan Compose Multiplatform, mempertahankan SwiftUI untuk seluruh aplikasi dan hanya berbagi logika, atau memadukan keduanya. Layar yang bergantung pada UX spesifik platform, seperti widget atau App Clips, biasanya dibiarkan native.

Mengonsumsi Kode Bersama Dari Swift di iOS

Modul bersama dikompilasi menjadi framework yang diimpor Swift seperti pustaka mana pun. Hambatan historisnya adalah fungsi suspend Kotlin dan Flow yang muncul sebagai API callback yang canggung. SKIE dari Touchlab menyelesaikannya dengan menghasilkan Swift yang idiomatik: suspend menjadi async/await native dan Flow menjadi AsyncSequence.

iosApp/ContentView.swiftswift
import SwiftUI
import Shared   // the KMP framework, baseName = "Shared"

struct ContentView: View {
    @State private var questions: [Question] = []
    private let repository = InterviewRepository()

    var body: some View {
        List(questions, id: \.id) { question in
            Text(question.prompt)
        }
        .task {
            // With SKIE, the Kotlin suspend fun is a Swift async fun
            questions = (try? await repository.fetchQuestions(tech: "android")) ?? []
        }
    }
}

Tim iOS menulis Swift dan SwiftUI biasa. Mereka mengonsumsi model dan repository bersama persis seperti paket Swift native, sehingga KMP tetap tak terlihat bagi sebagian besar basis kode iOS.

Dua sisi kasar masih layak disebut dalam wawancara. Pertama, waktu build: kompilasi Kotlin/Native lebih lambat daripada build Swift murni, meski cache build Gradle dan distribusi XCFramework prabuat meredam biaya hariannya. Kedua, debugging melintasi batas Swift-ke-Kotlin terus membaik tetapi belum semulus tetap berada dalam satu bahasa, dan itu alasan lain mengapa tim menjaga permukaan bersama tetap disengaja alih-alih membengkak.

Pertanyaan Wawancara Kotlin Multiplatform yang Perlu Diantisipasi

Karena pertanyaan wawancara KMP kian sering muncul pada peran Android dan mobile, beberapa yang berulang layak dilatih bersama persiapan wawancara Android yang lebih luas:

  • Apa beda expect/actual dengan sebuah interface? expect/actual diselesaikan saat kompilasi per target tanpa dispatch runtime dan dapat menopang kelas, fungsi, properti, atau typealias. Sebuah interface diselesaikan secara dinamis saat runtime. Gunakan expect/actual untuk API platform dan interface untuk polimorfisme di dalam kode bersama.
  • Bagaimana Kotlin/Native menangani memori dan threading? Sejak Kotlin 1.7.20 memory manager baru menghapus model pembekuan objek lama, sehingga state mutable bersama dan coroutine bekerja lintas thread hampir seperti di JVM.
  • Bisakah aplikasi yang sudah ada mengadopsi KMP secara bertahap? Bisa. Modul bersama dikirim sebagai AAR untuk Android dan XCFramework untuk iOS, sehingga satu repository atau fitur dapat bermigrasi satu per satu tanpa penulisan ulang.
  • Kapan UI sebaiknya tetap native alih-alih memakai Compose Multiplatform? Ketika sebuah layar bersandar pada UX spesifik platform atau ketika tim iOS memiliki dan lebih suka mengendalikan lapisan presentasi.
Toolchain pada 2026

Targetkan Kotlin 2.3 dengan kompiler K2, Ktor 3.x untuk jaringan, SQLDelight untuk basis data bersama, dan Koin untuk dependency injection. Untuk interop iOS, tambahkan SKIE sejak awal; memasangnya kembali setelah lapisan Swift ditulis jauh lebih menyakitkan.

Kesimpulan

Kotlin Multiplatform pada 2026 adalah cara pragmatis untuk memangkas logika ganda di Android dan iOS tanpa mengorbankan UI atau performa native:

  • Bagikan logika yang memiliki satu sumber kebenaran (model, jaringan, validasi) dan pilih UI native atau Compose per layar.
  • Gunakan expect/actual untuk API platform; mekanisme ini diselesaikan saat kompilasi tanpa overhead runtime.
  • Tulis jaringan sekali dengan Ktor dan kotlinx.serialization agar perbaikan mendarat di kedua platform sekaligus.
  • Adopsi secara bertahap melalui AAR dan XCFramework alih-alih berkomitmen pada penulisan ulang.
  • Tambahkan SKIE sejak awal agar Swift mengonsumsi suspend dan Flow sebagai async/await dan AsyncSequence native.

Mulai berlatih!

Uji pengetahuan Anda dengan simulator wawancara dan tes teknis kami.

Tag

#Kotlin Multiplatform
#KMP
#Android
#iOS
#Cross-platform

Bagikan

Artikel terkait