Slide 1

Slide 1 text

Sungyong An Jetpack for KMP

Slide 2

Slide 2 text

Sungyong An Android GDE @fornewid

Slide 3

Slide 3 text

“Multiplatform੉ۄҊ ೞݶ যڃ Ѫ੉ ځয়ܰաਃ?” 💬 Intro

Slide 4

Slide 4 text

Intro Function, UseCase ١ਵ۽ ௏٘ܳ ܻ࠙ೞח Ѫ੉ ੗োझۣ׮. ೞա੄ ೐۽ં౟ী ߈ࠂغח ௏٘о ੓׮ݶ? fun doSomething() { ... // repeated codes ... // repeated codes ... } fun doSomething() { ... repeat() ... repeat() ... } fun repeat() { // repeated codes }

Slide 5

Slide 5 text

Project A fun doSomething() { repeat() } Project B Intro زੌೠ ೒ۖಬ੉ۄݶ ۄ੉࠳۞ܻ۽ ௏٘ܳ ܻ࠙ೞৈ ઁҕೠ׮. ৈ۞ ೐۽ં౟ী ߈ࠂغח ௏٘о ੓׮ݶ? Library fun repeat() { // repeated codes } fun doSomething() { repeat() }

Slide 6

Slide 6 text

Intro JVM਷ ੗߄ ߄੉౟௏٘ܳ ೧ࢳೞৈ যڃ ೒ۖಬীࢲب زੌೞѱ प೯ೡ ࣻ ੓׮. ৈ۞ ೒ۖಬী زੌೠ ௏٘ ࢎਊೞח ߑߨ? Link: h tt ps://en.wikipedia.org/wiki/Java_vi rt ual_machine JVM OS Windows Linux macOS Hardware Program Program ... ...

Slide 7

Slide 7 text

Intro Kotlin Multiplatformਸ ࢎਊೞח Ѫب ೞա੄ ߑߨ! ৈ۞ ೒ۖಬী ߈ࠂغח ௏٘о ੓׮ݶ? Link: h tt ps://www.jetbrains.com/kotlin-multipla tf orm/ Client Multiplatform Common Multiplatform Server Android iOS Desktop Web

Slide 8

Slide 8 text

߈ࠂغח ௏٘ܳ ઴੉Ҋ र਷ ѐߊ੗੄ ৌݎ?! 🤔 Intro

Slide 9

Slide 9 text

Link: h tt ps://blog.jetbrains.com/kotlin/2023/11/kotlin-multipla tf orm-stable/ Intro

Slide 10

Slide 10 text

Hello, KMP! Kotlin Multiplatform Section 1 Link: h tt ps://www.jetbrains.com/kotlin-multipla tf orm/

Slide 11

Slide 11 text

Section 1 Desktop Android iOS Server

Slide 12

Slide 12 text

Section 1 Desktop Android iOS Server Kotlin/JVM Kotlin/JVM Kotlin/Native Kotlin/JVM

Slide 13

Slide 13 text

Section 1 Desktop Android iOS Server Domain

Slide 14

Slide 14 text

Section 1 Desktop Android iOS Server Data Domain

Slide 15

Slide 15 text

Section 1 Server Data Domain UI

Slide 16

Slide 16 text

Section 1 Server Data Domain UI ೐۽ં౟݃׮ ׮ܰѱ ਗೞח ݅ఀ݅ ੸ਊೡ ࣻ ੓׮.

Slide 17

Slide 17 text

Section 1 Common Android iOS Desktop KMP Module

Slide 18

Slide 18 text

Section 1 commonMain/ androidMain/ iosMain/ desktopMain/ KMP Module ✅ ❌ .kt .kt .kt .kt

Slide 19

Slide 19 text

// commonMain fun greet(platform: String = "Kotlin Multiplatform"): String { return "Hello, $platform!" } // androidMain greet(platform = "Android") // iosMain greet(platform = "iOS") // desktopMain greet(platform = "Desktop") ✅

Slide 20

Slide 20 text

// commonMain fun greet(): String { return "Hello, ${platform()}!" } // androidMain fun platform() = "Android" // iosMain fun platform() = "iOS" // desktopMain fun platform() = "Desktop" ❌

Slide 21

Slide 21 text

Section 1 commonMain/ androidMain/ iosMain/ desktopMain/ expect - actual expect actual actual actual ✅ Link: h tt ps://kotlinlang.org/docs/multipla tf orm-expect-actual.html

Slide 22

Slide 22 text

// commonMain fun greet(): String { return "Hello, ${platform()}!" } expect fun platform() // androidMain actual fun platform() = "Android" // iosMain actual fun platform() = "iOS" // desktopMain actual fun platform() = “Desktop" ✅

Slide 23

Slide 23 text

// commonMain fun greet(platform: Platform): String { return "Hello, ${platform.name}!" } expect class Platform { val name: String } // androidMain actual class Platform { actual val name: String get() = "Android" } // iosMain actual class Platform { actual val name: String get() = "iOS" } // desktopMain actual class Platform { actual val name: String get() = "Desktop" } ⚠ Beta

Slide 24

Slide 24 text

Supported Platforms Section 1 Link: h tt ps://www.jetbrains.com/help/kotlin-multipla tf orm-dev/suppo rt ed-pla tf orms.html Android Stable iOS Stable Desktop (JVM) Stable Server-side (JVM) Stable Web based on Kotlin/Wasm Alpha Web based on Kotlin/JS Stable watchOS, tvOS Best effort

Slide 25

Slide 25 text

Section 1 Targets kotlin { androidTarget() iosX64() iosArm64() iosSimulatorArm64() } common jvm android native js androidNative apple mingw linux ios macos tvos watchos iosSimulatorArm64 iosX64 iosArm64 Link: h tt ps://kotlinlang.org/docs/multipla tf orm-discover-project.html#targets

Slide 26

Slide 26 text

kotlin { sourceSets { commonMain.dependencies { implementation(libs.ktor.client.core) } androidMain.dependencies { implementation(libs.ktor.client.okhttp) } iosMain.dependencies { implementation(libs.ktor.client.darwin) } } } Source sets Section 1 Link: h tt ps://kotlinlang.org/docs/multipla tf orm-discover-project.html#source-sets commonMain androidMain iosMain

Slide 27

Slide 27 text

sourceSets { val commonMain by getting { dependencies { ... } } val jvmAndroidMain by creating { dependsOn(commonMain) dependencies { ... } } val androidMain by getting { dependsOn(jvmAndroidMain) } val desktopMain by getting { dependsOn(jvmAndroidMain) } } Additional source sets Section 1 desktopMain jvmAndroidMain androidMain commonMain

Slide 28

Slide 28 text

// Android - build.gradle.kts plugins { id("com.android.application") id("org.jetbrains.kotlin.android") } android { ... } dependencies { ... }

Slide 29

Slide 29 text

// Kotlin Multiplatform - build.gradle.kts plugins { id("com.android.application") id("org.jetbrains.kotlin.multiplatform") } android { ... } kotlin { androidTarget() sourceSets { commonMain.dependencies { ... } androidMain.dependencies { ... } } }

Slide 30

Slide 30 text

IDE Support Section 1 Link: h tt ps://www.jetbrains.com/help/kotlin-multipla tf orm-dev/recommended-ides.html Android Studio Fleet

Slide 31

Slide 31 text

🗂 org/jetbrains/kotlinx/ 🗂 kotlinx-coroutines-core/1.8.1/ - kotlinx-coroutines-core -1.8.1.jar 🗂 kotlinx-coroutines-core-jvm/1.8.1/ - kotlinx-coroutines-core-jvm -1.8.1.jar 🗂 kotlinx-coroutines-core-iosarm64/1.8.1/ - kotlinx-coroutines-core-iosarm64 -1.8.1.klib KMP Library Section 1 Non-platform source set’s Refer to h tt ps://www.youtube.com/watch?v=vU48FVzBLtc

Slide 32

Slide 32 text

kotlin { sourceSets { commonMain.dependencies { implementation("org.jetbrains.kotlinx: kotlinx-coroutines-core :1.8.1") } jvmMain.dependencies { implementation("org.jetbrains.kotlinx: kotlinx-coroutines-core-jvm :1.8.1") } iosArm64Main.dependencies { implementation("org.jetbrains.kotlinx: kotlinx-coroutines-core-iosarm64 :1.8.1”) } } } ❌

Slide 33

Slide 33 text

kotlin { sourceSets { commonMain.dependencies { implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.1") } // jvmMain.dependencies { // implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.8.1") // } // iosArm64Main.dependencies { // implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core-iosarm64:1.8.1") // } } }

Slide 34

Slide 34 text

kotlin { sourceSets { commonMain.dependencies { implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.1") } } } // jvmMain -> "org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.8.1" // iosArm64Main -> "org.jetbrains.kotlinx:kotlinx-coroutines-core-iosarm64:1.8.1" ✅

Slide 35

Slide 35 text

Link: h tt ps://youtu.be/_yWxUp86TGg?t=2215

Slide 36

Slide 36 text

Android Jetpack support Kotlin Multiplatform to share Business Logic. Jetpack for KMP Section 2

Slide 37

Slide 37 text

Android Jetpack Section 2 Link: h tt ps://developer.android.com/jetpack Collection Compose DataStore Activity ConstraintLayout Annotation AppCompat Browser Camera Fragment Core Glance Lifecycle ViewPager Navigation Paging Preference RecyclerView Room ViewModel Window WorkManager

Slide 38

Slide 38 text

App Domain UI App Architecture Section 2 Link: h tt ps://developer.android.com/topic/architecture Data Collection Compose DataStore Activity ConstraintLayout Annotation AppCompat Browser Fragment Core Lifecycle ViewPager Navigation Paging Preference RecyclerView Room ViewModel Window WorkManager

Slide 39

Slide 39 text

App Domain UI Jetpack supports KMP Section 2 Data Collection Annotation Core Link: h tt ps://developer.android.com/kotlin/multipla tf orm DataStore Paging Preference Room WorkManager Compose Activity ConstraintLayout AppCompat Browser Fragment Lifecycle ViewPager Navigation RecyclerView ViewModel Window

Slide 40

Slide 40 text

App Domain UI Jetpack supports KMP Section 2 Data Collection Annotation Core Link: h tt ps://developer.android.com/kotlin/multipla tf orm DataStore Paging Preference Room WorkManager Compose Activity ConstraintLayout AppCompat Browser Fragment Lifecycle ViewPager Navigation RecyclerView ViewModel Window

Slide 41

Slide 41 text

UI Domain Data To share Business Logic! Section 2 Collection Link: h tt ps://developer.android.com/kotlin/multipla tf orm DataStore Room Repository UseCase Compose ViewModel Lifecycle

Slide 42

Slide 42 text

• ArrayMap (JVM only) ਸ ઁ৻ೞݶ, ؀ࠗ࠙੄ ஸ۩࣌ਸ Ӓ؀۽ ࢎਊೡ ࣻ ੓׮. • SparseArray, LruCache, ... • ArrayMap ؀উਵ۽ ScatterMap ١ਸ ࢎਊೡ ࣻ ੓׮. • Romain Guy “A Better Hash Map — 1” ଵҊ https://www.romainguy.dev/posts/2024/a-better-hashmap/ Collection Section 2 Link: h tt ps://developer.android.com/jetpack/androidx/releases/collection

Slide 43

Slide 43 text

DataStore Section 2 androidx.datastore:datastore-core ✅ ✅ ✅ androidx.datastore:datastore-core-okio ✅ ✅ ✅ androidx.datastore:datastore-preferences-core ✅ ✅ ✅ androidx.datastore:datastore-preferences ✅ ❌ ✅ module Android iOS Desktop Link: h tt ps://developer.android.com/jetpack/androidx/releases/datastore

Slide 44

Slide 44 text

// Android // Setup dependencies { implementation("androidx.datastore:datastore-preferences:1.1.1") } // Create val Context.dataStore: DataStore by preferencesDataStore("settings") Link: h tt ps://developer.android.com/topic/libraries/architecture/datastore

Slide 45

Slide 45 text

// Android // Read val EXAMPLE_COUNTER = intPreferencesKey("example_counter") val exampleCounterFlow: Flow = context.dataStore.data.map { preferences -> preferences[EXAMPLE_COUNTER] ?: 0 } // Write suspend fun incrementCounter() { context.dataStore.edit { settings -> val currentCounterValue = settings[EXAMPLE_COUNTER] ?: 0 settings[EXAMPLE_COUNTER] = currentCounterValue + 1 } } Link: h tt ps://developer.android.com/topic/libraries/architecture/datastore

Slide 46

Slide 46 text

// Kotlin Multiplatform // Setup commonMain.dependencies { implementation("androidx.datastore:datastore-preferences-core:1.1.1") implementation("androidx.datastore:datastore-core-okio:1.1.1") implementation("com.squareup.okio:okio:3.9.0") } Link: h tt ps://developer.android.com/kotlin/multipla tf orm/datastore

Slide 47

Slide 47 text

// Kotlin Multiplatform // Create import okio.Path.Companion.toPath val dataStoreFileName = "datastore-name.preferences_pb" val datastore: DataStore = PreferenceDataStoreFactory.createWithPath( produceFile = { produceFilePath().toPath() }, ) Link: h tt ps://developer.android.com/kotlin/multipla tf orm/datastore // androidMain fun produceFilePath(): String { return context.filesDir.resolve(dataStoreFileName).absolutePath } // iosMain fun produceFilePath(): String = “${fileDirectory()}/$dataStoreFileName"

Slide 48

Slide 48 text

A modern I/O library Okio Section 2 Link: h tt ps://square.github.io/okio/

Slide 49

Slide 49 text

Room, SQLite Section 2 Link: h tt ps://developer.android.com/kotlin/multipla tf orm androidx.room:room-common ✅ ✅ ✅ androidx.room:room-runtime ✅ ✅ ✅ androidx.room:room-migration ✅ ✅ ✅ androidx.sqlite:sqlite ✅ ✅ ✅ androidx.sqlite:sqlite-framework ✅ ✅ ❌ androidx.sqlite:sqlite-bundled ✅ ✅ ✅ module Android iOS Desktop ❓ ❓

Slide 50

Slide 50 text

// Android // Setup dependencies { implementation("androidx.room:room-runtime:2.6.0") ksp("androidx.room:room-compiler:2.6.0") } // Entity @Entity data class User( @PrimaryKey(autoGenerate = true) val id: Long = 0, @ColumnInfo(name = "name") val name: String, ) Link: h tt ps://developer.android.com/training/data-storage/room

Slide 51

Slide 51 text

// Android // Data Access Object @Dao interface UserDao { @Query("SELECT * FROM user”) fun getAll(): List @Insert fun insertAll(vararg users: User) } // Database @Database(entities = [User::class], version = 1) abstract class AppDatabase : RoomDatabase() { abstract fun userDao(): UserDao } Link: h tt ps://developer.android.com/training/data-storage/room

Slide 52

Slide 52 text

// Android // Create val dbFileName = "database-name" val db = Room.databaseBuilder( applicationContext, AppDatabase::class.java, dbFileName, ).build() // Usage val userDao = db.userDao() val users: List = userDao.getAll() Link: h tt ps://developer.android.com/training/data-storage/room

Slide 53

Slide 53 text

// Kotlin Multiplatform // Setup commonMain.dependencies { implementation("androidx.room:room-runtime:2.7.0-alpha04") implementation("androidx.sqlite:sqlite-bundled:2.5.0-alpha04") } dependencies { add("kspAndroid", "androidx.room:room-compiler:2.7.0-alpha04") add("kspIosSimulatorArm64", "androidx.room:room-compiler:2.7.0-alpha04") add("kspIosX64", "androidx.room:room-compiler:2.7.0-alpha04") add("kspIosArm64", "androidx.room:room-compiler:2.7.0-alpha04") } // Entity (Same) // Database (Same) Link: h tt ps://developer.android.com/kotlin/multipla tf orm/room

Slide 54

Slide 54 text

// Kotlin Multiplatform // Data Access Object @Dao interface UserDao { // @Query("SELECT * FROM user") fun getAll(): List @Query("SELECT * FROM user") fun getAll(): Flow> // @Insert fun insertAll(vararg users: User) @Insert suspend fun insertAll(vararg users: User) } Link: h tt ps://developer.android.com/kotlin/multipla tf orm/room

Slide 55

Slide 55 text

// Kotlin Multiplatform // Usage - androidMain val dbFileName = "database-name.db" val db = Room.databaseBuilder( context = applicationContext, name = application.getDatabasePath(dbFileName), ) .setDriver(BundledSQLiteDriver()) // or AndroidSQLiteDriver .setQueryCoroutineContext(Dispatchers.IO) .build() Link: h tt ps://developer.android.com/kotlin/multipla tf orm/room ❓

Slide 56

Slide 56 text

Framework SQLite Android Common Native Android Native sqlite3.h android.database. SQLiteDatabase Android SQLite Driver Native SQLite Driver room-runtime sqlite-framework

Slide 57

Slide 57 text

Common Bundled SQLite Android Common Native Android Native sqlite3.c sqlite_jni.cpp room-runtime sqlite-bundled Bundled SQLite Driver

Slide 58

Slide 58 text

Link: h tt ps://developer.android.com/kotlin/multipla tf orm/room // Kotlin Multiplatform // Usage - iosMain val dbFileName = "database-name.db" val db = Room.databaseBuilder( name = "${fileDirectory()}/$dbFileName", factory = { AppDatabase::class.instantiateImpl() } ) .setDriver(BundledSQLiteDriver()) // or NativeSQLiteDriver .setQueryCoroutineContext(Dispatchers.IO) .build()

Slide 59

Slide 59 text

android/kotlin-multiplatform-samples Section 2 DiceRoller Fruitties Native UI + Preferences DataStore Native UI + Okio DataStore + Room

Slide 60

Slide 60 text

android/kotlin-multiplatform-samples Section 2 DiceRoller Fruitties Native UI + Preferences DataStore Native UI + Okio DataStore + Room

Slide 61

Slide 61 text

Android iOS Domain Data Jetpack Native UI UIө૑ ҕాചೞ۰ݶ? 🤔 Section 2

Slide 62

Slide 62 text

No content

Slide 63

Slide 63 text

Declarative framework for sharing UIs across multiple platforms. Compose Multiplatform Section 3

Slide 64

Slide 64 text

Supported platforms Section 3 Link: jb.gg/compose

Slide 65

Slide 65 text

forked from androidx/androidx Compose Multiplatform Core Section 3 Link: h tt ps://github.com/JetBrains/compose-multipla tf orm-core commonMain androidMain jbMain ... nativeMain desktopMain … webMain or skikoMain Jetpack Compose Compose Multiplatform

Slide 66

Slide 66 text

Starting Point! KMP Wizard Section 3 Link: h tt ps://kmp.jetbrains.com/

Slide 67

Slide 67 text

// Jetpack Compose dependencies { implementation("androidx. compose.runtime :runtime:1.6.7") implementation("androidx. compose.ui :ui:1.6.7") implementation("androidx. compose.foundation :foundation:1.6.7") implementation("androidx. compose.animation :animation:1.6.7") implementation("androidx. compose.material :material:1.6.7") implementation("androidx. compose.material3 :material3:1.2.1") } Link: h tt ps://developer.android.com/jetpack/androidx/releases/compose#versions

Slide 68

Slide 68 text

// Compose Multiplatform commonMain.dependencies { implementation("org.jetbrains. compose.runtime :runtime:1.6.11") implementation("org.jetbrains. compose.ui :ui:1.6.11") implementation("org.jetbrains. compose.foundation :foundation:1.6.11") implementation("org.jetbrains. compose.animation :animation:1.6.11") implementation("org.jetbrains. compose.material :material:1.6.11") implementation("org.jetbrains. compose.material3 :material3:1.6.11") } Link: h tt ps://www.jetbrains.com/help/kotlin-multipla tf orm-dev/compose-compatibility-and-versioning.html

Slide 69

Slide 69 text

// Compose Multiplatform plugins { id("org.jetbrains.compose") version "1.6.11" } commonMain.dependencies { implementation( compose.runtime ) implementation( compose.ui ) implementation( compose.foundation ) implementation( compose.animation ) implementation( compose.material ) implementation( compose.material3 ) }

Slide 70

Slide 70 text

KMP Wizard Section 3 commonMain androidMain iosMain desktopMain Desktop App Android App iOS App

Slide 71

Slide 71 text

@Composable KMP Wizard Section 3 App() ComposeView ComposeUIViewController ComposeWindow Window ComponentActivity SwiftUI

Slide 72

Slide 72 text

// Android class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { // ComposeView App() } } } // Desktop fun main() = application { Window(...) { // ComposeWindow App() } }

Slide 73

Slide 73 text

// iOS fun MainViewController(): UIViewController { return ComposeUIViewController { App() } } @main struct iOSApp: App { var body: some Scene { WindowGroup { ContentView() } } } struct ContentView: View { var body: some View { ComposeView() } } struct ComposeView: UIViewControllerRepresentable { func makeUIViewController(context: Context) -> UIViewController { MainViewControllerKt.MainViewController() } } Link: h tt ps://www.jetbrains.com/help/kotlin-multipla tf orm-dev/compose-swi ft ui-integration.html

Slide 74

Slide 74 text

org.jetbrains.compose.components:components-resources Resources Section 3 Link: h tt ps://www.jetbrains.com/help/kotlin-multipla tf orm-dev/compose-images-resources.html composeResources/ drawable files font value -fr -en-rUS -hdpi -dark

Slide 75

Slide 75 text

// Jetpack Compose android { android.buildFeatures.resValues = true // default } import com.example.kmp.R Image( painterResource(R.drawable.compose_multiplatform), contentDescription = null, )

Slide 76

Slide 76 text

// Compose Multiplatform commonMain.dependencies { implementation(compose.components.resources) } import kotlinproject.composeapp.generated.resources.Res import kotlinproject.composeapp.generated.resources.compose_multiplatform Image( painterResource(Res.drawable.compose_multiplatform), contentDescription = null, )

Slide 77

Slide 77 text

Lifecycle Section 3 androidx.lifecycle:lifecycle-common ✅ ✅ ✅ ❌ androidx.lifecycle:lifecycle-runtime ✅ ✅ ✅ ❌ androidx.lifecycle:lifecycle-runtime-compose ✅ ❌ ✅ ❌ org.jetbrains.androidx.lifecycle:lifecycle-common ✅ ✅ ✅ ✅ org.jetbrains.androidx.lifecycle:lifecycle-runtime ✅ ✅ ✅ ✅ org.jetbrains.androidx.lifecycle:lifecycle-runtime-compose ✅ ✅ ✅ ✅ Android iOS Desktop Web module Link: h tt ps://www.jetbrains.com/help/kotlin-multipla tf orm-dev/compose-lifecycle.html

Slide 78

Slide 78 text

Lifecycle Common Section 3 INITIALIZED DESTROYED CREATED STARTED RESUMED INITIALIZED DESTROYED CREATED STARTED RESUMED States Events States ON_PAUSE ON_RESUME ON_STOP ON_START ON_DESTROY ON_CREATE

Slide 79

Slide 79 text

Lifecycle to other platforms Section 3 Desktop iOS

Slide 80

Slide 80 text

Lifecycle to other platforms Section 3 Desktop iOS ViewControllerBasedLifecycleOwner.uikit.kt ComposeUIViewController.uikit.kt ✅ ComposeContainer.uikit.kt ComposeContainer.desktop.kt ✅ ComposeWindow.desktop.kt ComposeWindowPanel.desktop.kt LocalLifecycleOwner

Slide 81

Slide 81 text

ViewModel Section 3 Link: h tt ps://www.jetbrains.com/help/kotlin-multipla tf orm-dev/compose-viewmodel.html androidx.lifecycle:lifecycle-viewmodel ✅ ✅ ✅ ❌ androidx.lifecycle:lifecycle-viewmodel-compose ✅ ❌ ✅ ❌ org.jetbrains.androidx.lifecycle:lifecycle-viewmodel ✅ ✅ ✅ ✅ org.jetbrains.androidx.lifecycle:lifecycle-viewmodel-compose ✅ ✅ ✅ ✅ Android iOS Desktop Web module

Slide 82

Slide 82 text

// Jetpack Compose dependencies { implementation("androidx.lifecycle:lifecycle-viewmodel-compose:2.8.0") } @Composable fun CupcakeApp( viewModel: OrderViewModel = viewModel(), ) { ... } class OrderViewModel : ViewModel() { val uiState: StateFlow = ... }

Slide 83

Slide 83 text

// Compose Multiplatform commonMain.dependencies { implementation("org.jetbrains.androidx.lifecycle:lifecycle-viewmodel-compose:2.8.0") } @Composable fun CupcakeApp( viewModel: OrderViewModel = viewModel { OrderViewModel() }, ) { ... } class OrderViewModel : ViewModel() { val uiState: StateFlow = ... }

Slide 84

Slide 84 text

// Compose Multiplatform (Desktop) class OrderViewModel : ViewModel() { fun doSomething() { viewModelScope.launch { ... } } } // build.gradle.kts commonMain.dependencies { implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.1") } val desktopMain by getting desktopMain.dependencies { implementation("org.jetbrains.kotlinx:kotlinx-coroutines-swing:1.8.1") } // Dispatchers.Main.immediate

Slide 85

Slide 85 text

ViewModelStoreOwner Section 3 @Composable ComposeView ComposeUIViewController ComposeWindow ComponentActivity ✅ ✅ ✅ Desktop iOS Android LocalViewModelStoreOwner

Slide 86

Slide 86 text

@Composable NavHost NavBackStackEntry @Composable ✅ ViewModelStoreOwner Section 3 ComposeView ComposeUIViewController ComposeWindow ComponentActivity ✅ ✅ ✅ LocalViewModelStoreOwner NavBackStackEntry ✅ @Composable

Slide 87

Slide 87 text

Navigation Section 3 Link: h tt ps://www.jetbrains.com/help/kotlin-multipla tf orm-dev/compose-navigation-routing.html androidx.navigation:navigation-* ✅ ❌ ❌ ❌ org.jetbrains.androidx.navigation:navigation-common ✅ ✅ ✅ ✅ org.jetbrains.androidx.navigation:navigation-runtime ✅ ✅ ✅ ✅ org.jetbrains.androidx.navigation:navigation-compose ✅ ✅ ✅ ✅ Android iOS Desktop Web module

Slide 88

Slide 88 text

// Jetpack Compose dependencies { implementation("androidx.navigation:navigation-compose:2.7.7") } // Compose Multiplatform commonMain.dependencies { implementation("org.jetbrains.androidx.navigation:navigation-compose:2.7.0-alpha07") }

Slide 89

Slide 89 text

// Jetpack Compose // Compose Multiplatform val navController: NavHostController = rememberNavController() NavHost(navController, startDestination = "list") { composable("list") { ListScreen(onItemClick = { id -> navController.navigate("detail/$id") }) } composable( "detail/{id}", arguments = listOf(navArgument("id") { type = NavType.LongType }) ) { backStackEntry -> val id = backStackEntry.arguments?.getLong("id")!! DetailScreen(id = id) } }

Slide 90

Slide 90 text

JetBrains Internal ۄ੉࠳۞ܻ Section 3 androidx.annotation:annotation ✅ ✅ ✅ ❌ androidx.collection:collection ✅ ✅ ✅ ❌ org.jetbrains.compose.annotation-internal:annotation ✅ ✅ ✅ ✅ org.jetbrains.compose.collection-internal:collection ✅ ✅ ✅ ✅ Android iOS Desktop Web module

Slide 91

Slide 91 text

UI Compose ViewModel Lifecycle Domain Data To share UI Logic! Collection* DataStore Room Repository UseCase Compose ViewModel Lifecycle Collection* Navigation Section 3

Slide 92

Slide 92 text

Domain Summary Data Jetpack UI Android iOS Desktop But, in progress... 😅 ⚠ ⚠

Slide 93

Slide 93 text

Summary Try Kotlin Multiplatform! Kotlin Android Studio Jetpack Compose Link: jb.gg/kmp Gradle

Slide 94

Slide 94 text

Thank You! Sungyong An @fornewid Android GDE