Mobile Development Kotlin Subjective
Oct 04, 2025

Explain Kotlin multiplatform development and the expect/actual mechanism.

Detailed Explanation
Kotlin Multiplatform allows sharing code across platforms using expect/actual declarations for platform-specific implementations.\n\n**Project structure:**\n\nsrc/\n├── commonMain/kotlin/ # Shared code\n├── androidMain/kotlin/ # Android-specific\n├── iosMain/kotlin/ # iOS-specific\n├── jvmMain/kotlin/ # JVM-specific\n└── jsMain/kotlin/ # JavaScript-specific\n\n\n**Expect declarations (common module):**\n\n// commonMain/Platform.kt\nexpect class Platform() {\n val name: String\n val version: String\n}\n\nexpect fun getCurrentTimeMillis(): Long\n\nexpect object Logger {\n fun log(message: String)\n fun error(message: String, throwable: Throwable?)\n}\n\nexpected class DatabaseDriver {\n expect fun connect(url: String)\n expect fun query(sql: String): List>\n expect fun close()\n}\n\n\n**Actual implementations:**\n\n**Android:**\n\n// androidMain/Platform.kt\nactual class Platform actual constructor() {\n actual val name: String = "Android"\n actual val version: String = "${Build.VERSION.SDK_INT}"\n}\n\nactual fun getCurrentTimeMillis(): Long = System.currentTimeMillis()\n\nactual object Logger {\n actual fun log(message: String) {\n Log.d("KMP", message)\n }\n \n actual fun error(message: String, throwable: Throwable?) {\n Log.e("KMP", message, throwable)\n }\n}\n\nactual class DatabaseDriver {\n private var database: SQLiteDatabase? = null\n \n actual fun connect(url: String) {\n database = SQLiteDatabase.openDatabase(url, null, SQLiteDatabase.OPEN_READWRITE)\n }\n \n actual fun query(sql: String): List> {\n // SQLite implementation\n return emptyList()\n }\n \n actual fun close() {\n database?.close()\n }\n}\n\n\n**iOS:**\n\n// iosMain/Platform.kt\nimport platform.UIKit.UIDevice\nimport platform.Foundation.NSDate\n\nactual class Platform actual constructor() {\n actual val name: String = UIDevice.currentDevice.systemName\n actual val version: String = UIDevice.currentDevice.systemVersion\n}\n\nactual fun getCurrentTimeMillis(): Long {\n return (NSDate().timeIntervalSince1970 * 1000).toLong()\n}\n\nactual object Logger {\n actual fun log(message: String) {\n println("iOS Log: $message")\n }\n \n actual fun error(message: String, throwable: Throwable?) {\n println("iOS Error: $message")\n throwable?.printStackTrace()\n }\n}\n\nactual class DatabaseDriver {\n actual fun connect(url: String) {\n // Core Data or SQLite.swift implementation\n }\n \n actual fun query(sql: String): List> {\n // iOS-specific database query\n return emptyList()\n }\n \n actual fun close() {\n // Close iOS database connection\n }\n}\n\n\n**JVM:**\n\n// jvmMain/Platform.kt\nactual class Platform actual constructor() {\n actual val name: String = "JVM"\n actual val version: String = System.getProperty("java.version")\n}\n\nactual fun getCurrentTimeMillis(): Long = System.currentTimeMillis()\n\nactual object Logger {\n actual fun log(message: String) {\n println("JVM Log: $message")\n }\n \n actual fun error(message: String, throwable: Throwable?) {\n System.err.println("JVM Error: $message")\n throwable?.printStackTrace()\n }\n}\n\nactual class DatabaseDriver {\n private var connection: java.sql.Connection? = null\n \n actual fun connect(url: String) {\n connection = java.sql.DriverManager.getConnection(url)\n }\n \n actual fun query(sql: String): List> {\n // JDBC implementation\n return emptyList()\n }\n \n actual fun close() {\n connection?.close()\n }\n}\n\n\n**Shared business logic:**\n\n// commonMain/UserRepository.kt\nclass UserRepository {\n private val database = DatabaseDriver()\n private val platform = Platform()\n \n suspend fun getUsers(): List {\n Logger.log("Fetching users on ${platform.name}")\n \n return try {\n database.connect("users.db")\n val results = database.query("SELECT * FROM users")\n results.map { row ->\n User(\n id = row["id"] as Int,\n name = row["name"] as String,\n email = row["email"] as String\n )\n }\n } catch (e: Exception) {\n Logger.error("Failed to fetch users", e)\n emptyList()\n } finally {\n database.close()\n }\n }\n \n fun getCurrentTimestamp(): Long {\n return getCurrentTimeMillis()\n }\n}\n\n\n**Gradle configuration:**\n\n// build.gradle.kts\nkotlin {\n android()\n ios()\n jvm()\n js(BOTH) {\n browser()\n nodejs()\n }\n \n sourceSets {\n val commonMain by getting {\n dependencies {\n implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4")\n implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.4.1")\n }\n }\n \n val androidMain by getting {\n dependencies {\n implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2")\n }\n }\n \n val iosMain by getting {\n dependencies {\n // iOS-specific dependencies\n }\n }\n }\n}\n\n\n**Benefits:**\n• Share business logic across platforms\n• Platform-specific optimizations\n• Type-safe expect/actual contracts\n• Gradual adoption possible\n• Reduced code duplication\n• Consistent API across platforms\n\n**Use cases:**\n• Mobile apps (Android/iOS)\n• Cross-platform libraries\n• Server and client sharing models\n• Desktop applications\n• Web applications\n\n**Limitations:**\n• Platform-specific APIs require expect/actual\n• Build complexity increases\n• Debugging can be challenging\n• Not all Kotlin features available on all platforms\n• Learning curve for platform-specific implementations
Discussion (0)

No comments yet. Be the first to share your thoughts!

Share Your Thoughts
Feedback