### KMP Database Callback Example Source: https://developer.android.com/kotlin/multiplatform/room Example of a database callback for Kotlin Multiplatform using SQLiteConnection. ```kotlin object MyRoomCallback : RoomDatabase.Callback() { override fun onCreate(connection: SQLiteConnection) { // … } override fun onDestructiveMigration(connection: SQLiteConnection) { // … } override fun onOpen(connection: SQLiteConnection) { // … } } ``` -------------------------------- ### KMP Migration Subclass Example Source: https://developer.android.com/kotlin/multiplatform/room Example of a migration subclass for Kotlin Multiplatform using SQLiteConnection. ```kotlin object Migration_1_2 : Migration(1, 2) { override fun migrate(connection: SQLiteConnection) { // … } } ``` -------------------------------- ### Android Database Callback Example Source: https://developer.android.com/kotlin/multiplatform/room Example of a database callback for Android using SupportSQLiteDatabase. ```kotlin object MyRoomCallback : RoomDatabase.Callback() { override fun onCreate(db: SupportSQLiteDatabase) { // … } override fun onDestructiveMigration(db: SupportSQLiteDatabase) { // … } override fun onOpen(db: SupportSQLiteDatabase) { // … } } ``` -------------------------------- ### Android Migration Subclass Example Source: https://developer.android.com/kotlin/multiplatform/room Example of a migration subclass for Android using SupportSQLiteDatabase. ```kotlin object Migration_1_2 : Migration(1, 2) { override fun migrate(db: SupportSQLiteDatabase) { // … } } ``` -------------------------------- ### KMP Auto Migration Specification Subclass Example Source: https://developer.android.com/kotlin/multiplatform/room Example of an auto-migration specification subclass for Kotlin Multiplatform using SQLiteConnection. ```kotlin class AutoMigrationSpec_1_2 : AutoMigrationSpec { override fun onPostMigrate(connection: SQLiteConnection) { // … } } ``` -------------------------------- ### KMP RawQuery Runtime Query Creation Source: https://developer.android.com/kotlin/multiplatform/room Example of creating a RoomRawQuery at runtime for a KMP DAO function. ```kotlin suspend fun AppDatabase.getTodosWithLowercaseTitle(title: String): List { val query = RoomRawQuery( sql = "SELECT * FROM TodoEntity WHERE title = ?", onBindStatement = { it.bindText(1, title.lowercase()) } ) return todoDao().getTodos(query) } ``` -------------------------------- ### Configure Local Dependency Selection Source: https://developer.android.com/kotlin/multiplatform/plugin Configure strategies for selecting variants of external Android library dependencies within a KMP library. This example sets build type selection order and product flavor selection. ```kotlin // build.gradle.kts kotlin { android { localDependencySelection { // For dependencies with multiple build types, select 'debug' first, and 'release' in case 'debug' is missing selectBuildTypeFrom.set(listOf("debug", "release")) // For dependencies with a 'type' flavor dimension... productFlavorDimension("type") { // ...select the 'typeone' flavor. selectFrom.set(listOf("typeone")) } } } } ``` -------------------------------- ### Android Auto Migration Specification Subclass Example Source: https://developer.android.com/kotlin/multiplatform/room Example of an auto-migration specification subclass for Android using SupportSQLiteDatabase. ```kotlin class AutoMigrationSpec_1_2 : AutoMigrationSpec { override fun onPostMigrate(db: SupportSQLiteDatabase) { // … } } ``` -------------------------------- ### Configure Tasks for Specific Build Types Source: https://developer.android.com/kotlin/multiplatform/plugin Configure tasks for specific build types when multiple variants are present. This example selects the 'release' build type. ```kotlin // build.gradle.kts androidComponents { onVariants(selector().withBuildType("release")) { variant -> // ... } } ``` -------------------------------- ### Android RawQuery Runtime Query Creation Source: https://developer.android.com/kotlin/multiplatform/room Example of creating a SimpleSQLiteQuery at runtime for an Android DAO function. ```kotlin suspend fun AndroidOnlyDao.getTodosWithLowercaseTitle(title: String): List { val query = SimpleSQLiteQuery( query = "SELECT * FROM TodoEntity WHERE title = ?", bindArgs = arrayOf(title.lowercase()) ) return getTodos(query) } ``` -------------------------------- ### Using Room KMP Write Transactions with immediateTransaction Source: https://developer.android.com/kotlin/multiplatform/room Use `useWriterConnection` with `immediateTransaction` for atomic writes in Room KMP. This is the preferred choice for most write operations, acquiring a lock at the start. ```kotlin val database: RoomDatabase = … database.useWriterConnection { transactor -> transactor.immediateTransaction { // perform database operations in transaction } } ``` -------------------------------- ### Declare KMP Dependencies with SourceSets Source: https://developer.android.com/kotlin/multiplatform/setup Declare common and platform-specific dependencies for your shared module using Gradle sourceSets. This example shows how to add Ktor client dependencies for common, Android, and iOS platforms. ```kotlin sourceSets { commonMain.dependencies { //put your multiplatform dependencies here //... implementation(libs.ktor.client.core) implementation(libs.ktor.client.content.negotiation) implementation(libs.ktor.serialization.kotlinx.json) //... } androidMain.dependencies { implementation(libs.ktor.client.okhttp) } iosMain.dependencies { implementation(libs.ktor.client.darwin) } } ``` -------------------------------- ### Legacy Java Source Compilation (Default) Source: https://developer.android.com/kotlin/multiplatform/plugin In the legacy setup, Java compilation was enabled by default. The JVM target for both Java and Kotlin sources was set in the `android` block using `compileOptions`. ```kotlin // build.gradle.kts android { // ... compileOptions { sourceCompatibility = JavaVersion.VERSION_1_8 targetCompatibility = JavaVersion.VERSION_1_8 } } kotlin { androidTarget { compilations.all { kotlinOptions.jvmTarget = "1.8" } } } ``` -------------------------------- ### Create JVM (Desktop) DataStore Instance Source: https://developer.android.com/kotlin/multiplatform/datastore Provide a path for DataStore on JVM (Desktop) using Java or Kotlin APIs, such as the system's temporary directory. ```kotlin // shared/src/jvmMain/kotlin/createDataStore.desktop.kt fun createDataStore(): DataStore = createDataStore( storage = FileStorage( serializer = PreferencesSerializer, produceFile = { File(System.getProperty("java.io.tmpdir"), dataStoreFileName) } ) ) ``` -------------------------------- ### Create Web DataStore Instance Source: https://developer.android.com/kotlin/multiplatform/datastore Instantiate DataStore for Web platforms using WebLocalStorage or WebSessionStorage, specifying a name for the data store. ```kotlin // shared/src/jsMain/kotlin/createDataStore.web.kt (also works for wasmJsMain) fun createDataStore(): DataStore = createDataStore( storage = WebLocalStorage( serializer = PreferencesSerializer, name = dataStoreFileName ) ) ``` -------------------------------- ### Configure Host and Device Tests (New Plugin) Source: https://developer.android.com/kotlin/multiplatform/plugin Opt-in to enable and configure host-side (unit) and device-side (instrumented) tests using `withHostTest` and `withDeviceTest` blocks. Note the directory changes from `src/androidUnitTest` to `src/androidHostTest` and `src/androidInstrumentedTest` to `src/androidDeviceTest`. ```kotlin // build.gradle.kts kotlin { android { // ... // Opt-in to enable and configure host-side (unit) tests withHostTest { isIncludeAndroidResources = true } // Opt-in to enable and configure device-side (instrumented) tests withDeviceTest { instrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" execution = "HOST" } } } // Project Structure (After Opt-in) // └── src // ├── androidHostTest // └── androidDeviceTest ``` -------------------------------- ### Create iOS DataStore Instance Source: https://developer.android.com/kotlin/multiplatform/datastore Create a DataStore instance on iOS using OkioStorage, retrieving the path from NSDocumentDirectory. ```kotlin // shared/src/iosMain/kotlin/createDataStore.ios.kt fun createDataStore(): DataStore = createDataStore( storage = OkioStorage( fileSystem = FileSystem.SYSTEM, serializer = PreferencesSerializer, producePath = { val documentDirectory: NSURL? = NSFileManager.defaultManager.URLForDirectory( directory = NSDocumentDirectory, inDomain = NSUserDomainMask, appropriateForURL = null, create = false, error = null, ) (requireNotNull(documentDirectory).path + "/$dataStoreFileName").toPath() } ) ) ``` -------------------------------- ### Instantiate Room Database with BundledSQLiteDriver Source: https://developer.android.com/kotlin/multiplatform/room This function demonstrates how to build and instantiate an AppDatabase using a RoomDatabase.Builder. It configures the database to use the BundledSQLiteDriver and sets the query coroutine context to Dispatchers.IO. ```kotlin // shared/src/commonMain/kotlin/Database.kt fun getRoomDatabase( builder: RoomDatabase.Builder ): AppDatabase { return builder .setDriver(BundledSQLiteDriver()) .setQueryCoroutineContext(Dispatchers.IO) .build() } ``` -------------------------------- ### Instantiate ViewModel in SwiftUI View Source: https://developer.android.com/kotlin/multiplatform/viewmodel This SwiftUI View demonstrates how to use the `IosViewModelStoreOwner` as a `@StateObject` to retrieve and manage a `MainViewModel`. It shows how to pass the factory for dependency injection. ```swift // iosApp/ContentView.swift struct ContentView: View { /// Use the store owner as a StateObject to allow retrieving ViewModels and scoping it to this screen. @StateObject private var viewModelStoreOwner = IosViewModelStoreOwner() var body: some View { /// Retrieves the `MainViewModel` instance using the `viewModelStoreOwner`. /// The `MainViewModel.Factory` and `creationExtras` are provided to enable dependency injection /// and proper initialization of the ViewModel with its required `AppContainer`. let mainViewModel: MainViewModel = viewModelStoreOwner.viewModel( factory: MainViewModelKt.mainViewModelFactory ) // ... // .. the rest of the SwiftUI code } } ContentView.swift ``` -------------------------------- ### Create Android DataStore Instance Source: https://developer.android.com/kotlin/multiplatform/datastore Instantiate DataStore on Android using FileStorage, requiring a Context and the data store file name. ```kotlin // shared/src/androidMain/kotlin/createDataStore.android.kt fun createDataStore(): DataStore = createDataStore( storage = FileStorage( serializer = PreferencesSerializer, produceFile = { context.filesDir.resolve(dataStoreFileName) } ) ) ``` -------------------------------- ### Apply Room and KSP Gradle Plugins Source: https://developer.android.com/kotlin/multiplatform/room Apply the KSP and Room Gradle plugins in your module's build.gradle.kts file. ```kotlin plugins { alias(libs.plugins.ksp) alias(libs.plugins.androidx.room) } ``` -------------------------------- ### Configure Kotlin Multiplatform Targets Reactively Source: https://developer.android.com/kotlin/multiplatform/kmp-integration Use `targets.configureEach` to lazily configure each target added to the KMP project. Avoid `forEach` to prevent potential errors. ```kotlin import org.gradle.api.Plugin import org.gradle.api.Project import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension class MyPlugin : Plugin { override fun apply(project: Project) { project.plugins.withId("org.jetbrains.kotlin.multiplatform") { val kmpExtension = project.extensions.getByType(KotlinMultiplatformExtension::class.java) kmpExtension.targets.configureEach { target -> // 'target' is an instance of KotlinTarget val targetName = target.name // for example, "android", "iosX64", "jvm" val platformType = target.platformType // for example, androidJvm, jvm, native, js } } } } ``` -------------------------------- ### Apply plugin aliases in root build file (build.gradle.kts) Source: https://developer.android.com/kotlin/multiplatform/plugin In the root `build.gradle.kts` file, add plugin aliases using `apply false` to make them available to subprojects without applying the plugin logic to the root project. ```kotlin // Root build.gradle.kts file plugins { alias(libs.plugins.kotlin.multiplatform) apply false // Add the following alias(libs.plugins.android.kotlin.multiplatform.library) apply false } ``` -------------------------------- ### Standart Android Kitaplık Eklentisiyle Tüketici Proguard Kurallarını Belirtme Source: https://developer.android.com/kotlin/multiplatform/plugin?hl=tr com.android.library ile android.defaultConfig içinde consumerProguardFiles ile belirtilen tüm kural dosyaları, varsayılan olarak kitaplığın yapıtlarında yayınlanır. ```kotlin android { defaultConfig { consumerProguardFiles("consumer-proguard-rules.pro") } } ``` -------------------------------- ### Core SQLite Driver API Usage Source: https://developer.android.com/kotlin/multiplatform/sqlite Demonstrates opening a database, creating a table, inserting data, and querying records using the BundledSQLiteDriver. Use this for direct, low-level SQLite interactions in Kotlin Multiplatform projects. ```kotlin fun main() { val databaseConnection = BundledSQLiteDriver().open("todos.db") databaseConnection.execSQL( "CREATE TABLE IF NOT EXISTS Todo (id INTEGER PRIMARY KEY, content TEXT)" ) databaseConnection.prepare( "INSERT OR IGNORE INTO Todo (id, content) VALUES (? ,?)" ).use { stmt -> stmt.bindInt(index = 1, value = 1) stmt.bindText(index = 2, value = "Try Room in the KMP project.") stmt.step() } databaseConnection.prepare("SELECT content FROM Todo").use { stmt -> while (stmt.step()) { println("Action item: ${stmt.getText(0)}") } } databaseConnection.close() } ``` -------------------------------- ### Configure Custom Source Directories with Legacy Plugin Source: https://developer.android.com/kotlin/multiplatform/plugin With the legacy `com.android.library` plugin, the `sourceSets` block was used. `kotlin.setSrcDirs` replaces directories, while `assets.srcDir` appends. ```kotlin // build.gradle.kts android { sourceSets { getByName("main") { // Replaces the directory for Kotlin sources. kotlin.setSrcDirs(listOf("other/kotlin")) // Appends a directory for assets. assets.srcDir("other/assets") } } } ``` -------------------------------- ### Declare Android-KMP plugin in version catalog Source: https://developer.android.com/kotlin/multiplatform/plugin Define plugin IDs and versions in the `gradle/libs.versions.toml` file. Ensure you have the correct versions for AGP and KGP. ```toml # To check the version number of the latest Kotlin release, go to # https://kotlinlang.org/docs/releases.html [versions] androidGradlePlugin = "9.2.0" kotlin = "KOTLIN_VERSION" [plugins] kotlin-multiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" } android-kotlin-multiplatform-library = { id = "com.android.kotlin.multiplatform.library", version.ref = "androidGradlePlugin" } ``` -------------------------------- ### Configure Tests (Legacy Plugin) Source: https://developer.android.com/kotlin/multiplatform/plugin With the `com.android.library` plugin, `androidUnitTest` and `androidInstrumentedTest` source sets are created by default. Configure their behavior using the `testOptions` DSL. ```kotlin // build.gradle.kts android { defaultConfig { // Runner was configured in defaultConfig testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" } testOptions { // Configure unit tests (for the 'test' source set) unitTests.isIncludeAndroidResources = true // Configure device tests (for the 'androidTest' source set) execution = "HOST" } } // Project Structure (Defaults) // └── src // ├── test // └── androidTest ``` -------------------------------- ### Add DataStore Dependencies Source: https://developer.android.com/kotlin/multiplatform/datastore Add the necessary DataStore and Preferences DataStore artifacts to your KMP module's build.gradle.kts file. ```kotlin commonMain.dependencies { // DataStore library implementation("androidx.datastore:datastore:1.2.1") // The Preferences DataStore library implementation("androidx.datastore:datastore-preferences:1.2.1") } ``` -------------------------------- ### Add Room runtime and bundled SQLite dependencies Source: https://developer.android.com/kotlin/multiplatform/room Include the Room runtime and the bundled SQLite library for common main sources. ```kotlin commonMain.dependencies { implementation(libs.androidx.room.runtime) implementation(libs.androidx.sqlite.bundled) } ``` -------------------------------- ### Execute Query with Result and Arguments using SQLiteConnection Source: https://developer.android.com/kotlin/multiplatform/sqlite Prepare and execute a SQL query with arguments using `SQLiteConnection`. Bind arguments to the statement and check if a row is found. ```kotlin connection.prepare("SELECT * FROM Pet WHERE id = ?").use { statement -> statement.bindInt(1, id) if (statement.step()) { // row found, read columns } else { // row not found } } ``` -------------------------------- ### Define Room versions and libraries in libs.versions.toml Source: https://developer.android.com/kotlin/multiplatform/room Specify Room, SQLite, and KSP versions and their corresponding library modules in the TOML file. ```toml [versions] room = "2.8.4" sqlite = "2.6.2" ksp = "" [libraries] androidx-sqlite-bundled = { module = "androidx.sqlite:sqlite-bundled", version.ref = "sqlite" } androidx-room-runtime = { module = "androidx.room:room-runtime", version.ref = "room" } androidx-room-compiler = { module = "androidx.room:room-compiler", version.ref = "room" } # Optional SQLite Wrapper available in version 2.8.0 and higher androidx-room-sqlite-wrapper = { module = "androidx.room:room-sqlite-wrapper", version.ref = "room" } [plugins] ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" } androidx-room = { id = "androidx.room", version.ref = "room" } ``` -------------------------------- ### Apply Android-KMP plugin in module build file (build.gradle) Source: https://developer.android.com/kotlin/multiplatform/plugin In the module-specific `build.gradle` file, apply the Android-KMP plugin at the top of the `plugins` block. ```groovy // Module-specific build.gradle file plugins { alias(libs.plugins.kotlin.multiplatform) // Add the following alias(libs.plugins.android.kotlin.multiplatform.library) } ``` -------------------------------- ### Publish Consumer Keep Rules Source: https://developer.android.com/kotlin/multiplatform/plugin Enable publishing of consumer keep rules for KMP libraries with the new plugin by setting optimization.consumerKeepRules.publish to true and specifying rule files. ```kotlin // build.gradle.kts kotlin { android { optimization { consumerKeepRules.apply { publish = true file("consumer-proguard-rules.pro") } } } } ``` -------------------------------- ### Define ViewModel Version and Library Source: https://developer.android.com/kotlin/multiplatform/viewmodel Define the version and library for the AndroidX ViewModel in your `libs.versions.toml` file. ```toml [versions] androidx-viewmodel = 2.11.0 [libraries] androidx-lifecycle-viewmodel = { module = "androidx.lifecycle:lifecycle-viewmodel", version.ref = "androidx-viewmodel" } ``` -------------------------------- ### Configure Java and Kotlin Options (Legacy) Source: https://developer.android.com/kotlin/multiplatform/plugin If not using Kotlin toolchain, configure JVM targets separately for Java and Kotlin using compileOptions and kotlinOptions blocks. ```kotlin // build.gradle.kts android { compileOptions { sourceCompatibility = JavaVersion.VERSION_11 targetCompatibility = JavaVersion.VERSION_11 } kotlinOptions { jvmTarget = "11" } } ``` -------------------------------- ### Yeni Eklentiyle Tüketici Saklama Kurallarını Yayınlama Source: https://developer.android.com/kotlin/multiplatform/plugin?hl=tr Yeni KMP eklentisiyle tüketici saklama kurallarını yayınlamak için optimization.consumerKeepRules.publish = true ayarlayın ve consumerKeepRules bloğunda kural dosyalarını belirtin. ```kotlin kotlin { android { optimization { consumerKeepRules.apply { publish = true file("consumer-proguard-rules.pro") } } } } ``` -------------------------------- ### Standart Android Kitaplık Eklentisiyle Ayrı compileOptions ve kotlinOptions Kullanma Source: https://developer.android.com/kotlin/multiplatform/plugin?hl=tr Kotlin araç zincirini kullanmıyorsanız, JVM hedeflerini Java ve Kotlin için ayrı bloklar kullanarak yapılandırmanız gerekir. ```kotlin android { compileOptions { sourceCompatibility = JavaVersion.VERSION_11 targetCompatibility = JavaVersion.VERSION_11 } kotlinOptions { jvmTarget = "11" } } ``` -------------------------------- ### Apply plugin aliases in root build file (build.gradle) Source: https://developer.android.com/kotlin/multiplatform/plugin In the root `build.gradle` file, add plugin aliases using `apply false` to make them available to subprojects without applying the plugin logic to the root project. ```groovy // Root build.gradle file plugins { alias(libs.plugins.kotlin.multiplatform) apply false // Add the following alias(libs.plugins.android.kotlin.multiplatform.library) apply false } ``` -------------------------------- ### Apply Android-KMP plugin in module build file (build.gradle.kts) Source: https://developer.android.com/kotlin/multiplatform/plugin In the module-specific `build.gradle.kts` file, apply the Android-KMP plugin at the top of the `plugins` block. ```kotlin // Module-specific build.gradle.kts file plugins { alias(libs.plugins.kotlin.multiplatform) // Add the following alias(libs.plugins.android.kotlin.multiplatform.library) } ``` -------------------------------- ### Execute Query with Result (No Arguments) using SQLiteConnection Source: https://developer.android.com/kotlin/multiplatform/sqlite Prepare and execute a SQL query that returns results but takes no arguments using `SQLiteConnection`. Iterate through the statement's steps to read column data. ```kotlin val connection: SQLiteConnection = ... connection.prepare("SELECT * FROM Pet").use { statement -> while (statement.step()) { // read columns statement.getInt(0) statement.getText(1) } } ``` -------------------------------- ### Derleme Düzeyinde Derleyici Seçeneklerini Kullanarak JVM Hedefini Ayarlama Source: https://developer.android.com/kotlin/multiplatform/plugin?hl=tr Belirli bir derlemenin farklı bir JVM sürümünü hedeflemesi gerektiğinde, derleyici seçeneklerini derleme başına yapılandırın. Bu ayar, hem Kotlin araç zincirini hem de Android hedef düzeyindeki seçenekleri geçersiz kılar. ```kotlin kotlin { android { compilations.all { compileTaskProvider.configure { compilerOptions.jvmTarget.set(JvmTarget.JVM_11) } } } } ``` -------------------------------- ### Execute Query with Result and Arguments using SupportSQLiteDatabase Source: https://developer.android.com/kotlin/multiplatform/sqlite Execute a SQL query with arguments using `SupportSQLiteDatabase`. Pass arguments to the query method and check if a row is found using the cursor. ```kotlin database.query("SELECT * FROM Pet WHERE id = ?", id).use { cursor -> if (cursor.moveToNext()) { // row found, read columns } else { // row not found } } ``` -------------------------------- ### JVM (Desktop) Room Database Builder Source: https://developer.android.com/kotlin/multiplatform/room Defines the Room database builder for JVM (Desktop), providing the database path using Java or Kotlin APIs, typically in the system's temporary directory. ```kotlin // shared/src/jvmMain/kotlin/Database.desktop.kt fun getDatabaseBuilder(): RoomDatabase.Builder { val dbFile = File(System.getProperty("java.io.tmpdir"), "my_room.db") return Room.databaseBuilder( name = dbFile.absolutePath, ) } ``` -------------------------------- ### Enable Android Resource Processing Source: https://developer.android.com/kotlin/multiplatform/plugin Enable Android resource processing by setting `enable = true` within the `androidResources` block. Resources should be placed in `src/androidMain/res`. ```kotlin // build.gradle.kts kotlin { android { // ... // Enable Android resource processing androidResources { enable = true } } } // Project Structure // └── src // └── androidMain // └── res // ├── values // │ └── strings.xml // └── drawable // └── icon.xml ``` -------------------------------- ### Check for Kotlin Multiplatform Plugin Source: https://developer.android.com/kotlin/multiplatform/kmp-integration Use `plugins.withId()` to react to the KMP plugin being applied. This approach is more robust than checking immediately. ```kotlin import org.gradle.api.Plugin import org.gradle.api.Project class MyPlugin : Plugin { override fun apply(project: Project) { project.plugins.withId("org.jetbrains.kotlin.multiplatform") { // The KMP plugin is applied, you can now configure your KMP integration. } } } ``` -------------------------------- ### Execute Query with Result (No Arguments) using SupportSQLiteDatabase Source: https://developer.android.com/kotlin/multiplatform/sqlite Execute a SQL query that returns results but takes no arguments using `SupportSQLiteDatabase`. Use the cursor to move through rows and read column data. ```kotlin val database: SupportSQLiteDatabase = ... database.query("SELECT * FROM Pet").use { cursor -> while (cusor.moveToNext()) { // read columns cursor.getInt(0) cursor.getString(1) } } ``` -------------------------------- ### Configure Shared Module for iOS Framework Source: https://developer.android.com/kotlin/multiplatform/migrate Configure the shared module's build.gradle.kts to produce a framework for different iOS architectures. The base name of the framework can be customized. ```kotlin val xcfName = "sharedKit" iosX64 { binaries.framework { baseName = xcfName } } iosArm64 { binaries.framework { baseName = xcfName } } iosSimulatorArm64 { binaries.framework { baseName = xcfName } } ``` -------------------------------- ### Configure Default Target SDK for Device Tests Source: https://developer.android.com/kotlin/multiplatform/kmp-integration This snippet demonstrates how to set a default `targetSdk` for Android device tests within a convention plugin. It uses `configureEach` to ensure the configuration is applied lazily and only when the test compilation is explicitly enabled by a module. ```kotlin import com.android.build.api.dsl.KotlinMultiplatformAndroidDeviceTestCompilation import com.android.build.api.dsl.KotlinMultiplatformAndroidLibraryTarget import org.gradle.api.Plugin import org.gradle.api.Project import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension class MyPlugin : Plugin { override fun apply(project: Project) { project.plugins.withId("com.android.kotlin.multiplatform.library") { val kmpExtension = project.extensions.getByType(KotlinMultiplatformExtension::class.java) kmpExtension.targets.withType(KotlinMultiplatformAndroidLibraryTarget::class.java) .configureEach { androidTarget -> androidTarget.compilations.withType( KotlinMultiplatformAndroidDeviceTestCompilation::class.java ).configureEach { targetSdk { version = release(34) } } } } } } ``` -------------------------------- ### Keep Room Database Implementation for ProGuard Source: https://developer.android.com/kotlin/multiplatform/room Include this ProGuard rule to ensure Room can find its generated implementation when the project is minified or obfuscated. ```proguard -keep class * extends androidx.room.RoomDatabase { (); } ``` -------------------------------- ### Android Hedef Düzeyinde Derleyici Seçeneklerini Kullanarak JVM Hedefini Ayarlama Source: https://developer.android.com/kotlin/multiplatform/plugin?hl=tr Android KMP hedefi için JVM hedef sürümünü belirtin. Bu ayar, proje genelindeki jvmToolchain yapılandırmasını geçersiz kılar ve tüm Android derlemeleri için geçerlidir. ```kotlin kotlin { android { compilerOptions { jvmTarget.set(JvmTarget.JVM_11) } } } ``` -------------------------------- ### Kotlin Araç Zincirini Kullanarak JVM Hedefini Ayarlama Source: https://developer.android.com/kotlin/multiplatform/plugin?hl=tr Projenizdeki tüm JVM tabanlı hedefler için hem Kotlin hem de Java derleyicilerinin hedef JVM sürümünü ayarlayın. Bu, tutarlı bir temel oluşturmak için harikadır. ```kotlin kotlin { jvmToolchain(21) } ``` -------------------------------- ### Enable Java Source Compilation (New Plugin) Source: https://developer.android.com/kotlin/multiplatform/plugin Opt-in to Java source compilation for the Android target by calling `withJava()`. Configure the JVM target for both Kotlin and Java sources within the `kotlin { android {} }` block. ```kotlin // build.gradle.kts kotlin { android { // Opt-in to enable Java source compilation withJava() // Configure the JVM target for both Kotlin and Java sources compilerOptions { jvmTarget.set(org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_1_8) } } // ... } // Project Structure: // └── src // └── androidMain // ├── kotlin // │ └── com/example/MyKotlinClass.kt // └── java // └── com.example/MyJavaClass.java ``` -------------------------------- ### Create Common DataStore Instance Source: https://developer.android.com/kotlin/multiplatform/datastore Define a common function to create a DataStore instance using DataStoreFactory. This function can be shared across all platforms. ```kotlin // shared/src/commonMain/kotlin/createDataStore.kt /** * Gets the singleton DataStore instance, creating it if necessary. */ fun createDataStore(storage: Storage): DataStore = DataStoreFactory.create(storage = storage) internal const val dataStoreFileName = "dice.preferences_pb" ``` -------------------------------- ### Publish Consumer Proguard Files (Legacy) Source: https://developer.android.com/kotlin/multiplatform/plugin With com.android.library, any rules files specified with consumerProguardFiles in android.defaultConfig are published in the library's artifacts by default. ```kotlin // build.gradle.kts android { defaultConfig { consumerProguardFiles("consumer-proguard-rules.pro") } } ``` -------------------------------- ### Access Kotlin Multiplatform Extension Source: https://developer.android.com/kotlin/multiplatform/kmp-integration Retrieve the `KotlinMultiplatformExtension` to configure KMP settings after the plugin is applied. ```kotlin import org.gradle.api.Plugin import org.gradle.api.Project import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension class MyPlugin : Plugin { override fun apply(project: Project) { project.plugins.withId("org.jetbrains.kotlin.multiplatform") { val kmpExtension = project.extensions.getByType(KotlinMultiplatformExtension::class.java) } } } ``` -------------------------------- ### Configure Custom Source Directories with New Plugin Source: https://developer.android.com/kotlin/multiplatform/plugin Use the `androidComponents` extension and `onVariants` block to add static source directories for Kotlin and assets with the new plugin. The `addStaticSourceDirectory` method appends to existing lists. ```kotlin // build.gradle.kts androidComponents { onVariants { variant -> // Add a directory for Kotlin sources variant.sources.kotlin?.addStaticSourceDirectory("other/kotlin") // Add a directory for Android assets variant.sources.assets?.addStaticSourceDirectory("other/assets") } } ``` -------------------------------- ### Add Compose Preview Dependency to Runtime Classpath Source: https://developer.android.com/kotlin/multiplatform/plugin Add a dependency, such as Compose Preview tooling, directly to the runtime classpath configuration of the main Android compilation. This makes it available at runtime but not part of the compile classpath or published API. ```kotlin // build.gradle.kts dependencies { "androidRuntimeClasspath"(libs.androidx.compose.ui.tooling) } ``` -------------------------------- ### Add SQLite Dependencies for KMP Source: https://developer.android.com/kotlin/multiplatform/sqlite Add the androidx.sqlite and androidx.sqlite-bundled artifacts to your module's build.gradle.kts file. Ensure you are using version 2.5.0 or higher for KMP support. ```kotlin plugins { id("com.google.devtools.ksp") version "1.9.22-1.0.17" } [versions] sqlite = "2.6.2" [libraries] # The SQLite Driver interfaces androidx-sqlite = { module = "androidx.sqlite:sqlite", version.ref = "sqlite" } # The bundled SQLite driver implementation androidx-sqlite-bundled = { module = "androidx.sqlite:sqlite-bundled", version.ref = "sqlite" } ``` -------------------------------- ### Using Android's withTransaction API Source: https://developer.android.com/kotlin/multiplatform/room This snippet shows the Android-only `withTransaction` API, which is equivalent to Room KMP's `useWriterConnection { it.immediateTransaction{ … } }`. ```kotlin val database: RoomDatabase = … database.withTransaction { // perform database operations in transaction } ``` -------------------------------- ### Add Compose Preview Dependency for Debug Builds Source: https://developer.android.com/kotlin/multiplatform/plugin Scope a dependency like Compose Preview tooling to the debug build type using `debugImplementation`. This ensures the dependency is available for debug builds but not included in the library's release variant. ```kotlin // build.gradle.kts dependencies { debugImplementation(libs.androidx.compose.ui.tooling) } ``` -------------------------------- ### Add KSP compiler dependencies for all targets Source: https://developer.android.com/kotlin/multiplatform/room Add the Room compiler KSP dependency for each platform target your application uses. ```kotlin dependencies { add("kspAndroid", libs.androidx.room.compiler) add("kspIosSimulatorArm64", libs.androidx.room.compiler) add("kspIosX64", libs.androidx.room.compiler) add("kspIosArm64", libs.androidx.room.compiler) // Add any other platform target you use in your project, for example kspDesktop } ``` -------------------------------- ### Define Room schema directory Source: https://developer.android.com/kotlin/multiplatform/room Configure the directory where Room schemas will be generated using the Room Gradle Plugin. ```kotlin room { schemaDirectory("$projectDir/schemas") } ``` -------------------------------- ### Legacy Android Resource Processing (Default) Source: https://developer.android.com/kotlin/multiplatform/plugin In the legacy plugin, resource processing was enabled by default. Resources could be added to `src/main/res` without extra configuration. ```kotlin // build.gradle.kts android { namespace = "com.example.library" compileSdk = 34 // No extra configuration was needed to enable resources. } // Project Structure // └── src // └── main // └── res // ├── values // │ └── strings.xml // └── drawable // └── icon.xml ``` -------------------------------- ### Using Room KMP Read Transactions with deferredTransaction Source: https://developer.android.com/kotlin/multiplatform/room Employ `useReaderConnection` with `deferredTransaction` for consistent reading operations in Room KMP. This allows readers to access the database while transactions are pending. ```kotlin val database: RoomDatabase = … database.useReaderConnection { transactor -> transactor.deferredTransaction { // perform database operations in transaction } } ``` -------------------------------- ### Export ViewModel Dependency for Swift Access Source: https://developer.android.com/kotlin/multiplatform/viewmodel Export the ViewModel dependency to the iOS binary framework in `build.gradle.kts` to make ViewModel APIs directly accessible from Swift. ```kotlin listOf( iosX64(), iosArm64(), iosSimulatorArm64(), ).forEach { it.binaries.framework { // Add this line to all the targets you want to export this dependency export(libs.androidx.lifecycle.viewmodel) baseName = "shared" } } ``` -------------------------------- ### Define ViewModel in commonMain Source: https://developer.android.com/kotlin/multiplatform/viewmodel Define a ViewModel class and its factory in the `commonMain` source set. Ensure no platform-specific APIs are used directly within the ViewModel. ```kotlin // commonMain/MainViewModel.kt class MainViewModel( private val repository: DataRepository, ) : ViewModel() { /* some logic */ } // ViewModelFactory that retrieves the data repository for your app. val mainViewModelFactory = viewModelFactory { initializer { MainViewModel(repository = getDataRepository()) } } fun getDataRepository(): DataRepository = DataRepository() MainViewModel.kt ``` -------------------------------- ### Handle Android-Specific KMP Integration Details Source: https://developer.android.com/kotlin/multiplatform/kmp-integration This snippet differentiates between old and new KMP Android integration points. It checks for `KotlinAndroidTarget` (for `com.android.library` or `com.android.application`) and `KotlinMultiplatformAndroidLibraryTarget` (for `com.android.kotlin.multiplatform.library`). Ensure AGP 7.1+ for `AndroidPluginVersion.getCurrent()` and AGP 8.8.0+ for `KotlinMultiplatformAndroidLibraryTarget`. ```kotlin import com.android.build.api.AndroidPluginVersion import com.android.build.api.dsl.KotlinMultiplatformAndroidLibraryTarget import org.gradle.api.Plugin import org.gradle.api.Project import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinAndroidTarget class MyPlugin : Plugin { override fun apply(project: Project) { project.plugins.withId("com.android.kotlin.multiplatform.library") { val kmpExtension = project.extensions.getByType(KotlinMultiplatformExtension::class.java) kmpExtension.targets.configureEach { target -> if (target is KotlinAndroidTarget) { // Old kmp android integration using com.android.library or com.android.application } if (AndroidPluginVersion.getCurrent() >= AndroidPluginVersion(8, 8) && target is KotlinMultiplatformAndroidLibraryTarget ) { // New kmp android integration using com.android.kotlin.multiplatform.library } } } } } ``` -------------------------------- ### Accessing Kotlin Compilations and Source Sets in KMP Source: https://developer.android.com/kotlin/multiplatform/kmp-integration This snippet demonstrates how to access and configure Kotlin compilations and their default source sets within an Android Kotlin Multiplatform library project using a Gradle plugin. It iterates through targets and compilations, providing access to compilation names and source sets. ```kotlin import com.android.build.api.dsl.KotlinMultiplatformAndroidCompilation import org.gradle.api.Plugin import org.gradle.api.Project import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension class MyPlugin : Plugin { override fun apply(project: Project) { project.plugins.withId("com.android.kotlin.multiplatform.library") { val kmpExtension = project.extensions.getByType(KotlinMultiplatformExtension::class.java) kmpExtension.targets.configureEach { target -> target.compilations.configureEach { compilation -> // standard compilations are usually 'main' and 'test' // android target has 'main', 'hostTest', 'deviceTest' val compilationName = compilation.name // Access the default source set for this compilation val defaultSourceSet = compilation.defaultSourceSet // Access the Android-specific compilation DSL if (compilation is KotlinMultiplatformAndroidCompilation) { } // Access and configure the Kotlin compilation task compilation.compileTaskProvider.configure { compileTask -> } } } } } } ``` -------------------------------- ### Add optional Room SQLite Wrapper dependency Source: https://developer.android.com/kotlin/multiplatform/room Include the Room SQLite Wrapper dependency for Android main sources if needed. ```kotlin // Optional when using Room SQLite Wrapper androidMain.dependencies { implementation(libs.androidx.room.sqlite.wrapper) } ``` -------------------------------- ### Declare Android Dependencies with New Plugin Source: https://developer.android.com/kotlin/multiplatform/plugin Declare Android-specific dependencies within the `androidMain` source set using the `sourceSets` block in the `kotlin` configuration. This promotes a cleaner structure compared to the legacy plugin. ```kotlin // build.gradle.kts kotlin { android {} //... other targets sourceSets { commonMain.dependencies { implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.0") } // Dependencies are now scoped to the specific Android source set androidMain.dependencies { implementation("androidx.appcompat:appcompat:1.7.0") implementation("com.google.android.material:material:1.11.0") } } } ``` -------------------------------- ### Accessing Android KMP Extension in a Gradle Plugin Source: https://developer.android.com/kotlin/multiplatform/kmp-integration This snippet demonstrates how to access the `KotlinMultiplatformAndroidLibraryTarget` within a Gradle plugin to configure Android-specific settings like `compileSdk` and `namespace`. ```kotlin import com.android.build.api.dsl.KotlinMultiplatformAndroidLibraryTarget import org.gradle.api.Plugin import org.gradle.api.Project import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension import org.jetbrains.kotlin.gradle.plugin.KotlinMultiplatformPluginWrapper class MyPlugin : Plugin { override fun apply(project: Project) { project.plugins.withId("com.android.kotlin.multiplatform.library") { val kmpExtension = project.extensions.getByType(KotlinMultiplatformExtension::class.java) // Access the Android target, which also serves as the Android-specific DSL extension kmpExtension.targets.withType(KotlinMultiplatformAndroidLibraryTarget::class.java).configureEach { androidTarget -> // You can now access properties and methods from both // KotlinMultiplatformAndroidLibraryTarget and KotlinMultiplatformAndroidLibraryExtension androidTarget.compileSdk = 34 androidTarget.namespace = "com.example.myplugin.library" androidTarget.withJava() // enable Java sources } } } } ``` -------------------------------- ### Configure iOS Linker Option for NativeSQLiteDriver Source: https://developer.android.com/kotlin/multiplatform/room This Gradle script snippet shows how to add the required linker option '-lsqlite3' for iOS targets when using the NativeSQLiteDriver. This ensures the iOS app dynamically links with the system SQLite library. ```kotlin // shared/build.gradle.kts kotlin { listOf( iosX64(), iosArm64(), iosSimulatorArm64() ).forEach { iosTarget -> iosTarget.binaries.framework { baseName = "TodoApp" isStatic = true // Required when using NativeSQLiteDriver linkerOpts.add("-lsqlite3") } } } ``` -------------------------------- ### Add ViewModel Dependency to KMP Module Source: https://developer.android.com/kotlin/multiplatform/viewmodel Add the ViewModel artifact to your KMP module's `build.gradle.kts` file using the 'api' declaration for better Swift access. ```kotlin commonMain.dependencies { api(libs.androidx.lifecycle.viewmodel) } ``` -------------------------------- ### Define Todo Entity Class Source: https://developer.android.com/kotlin/multiplatform/room Define the Room entity class representing a Todo item. This class should be placed in the common main source set. ```kotlin // shared/src/commonMain/kotlin/TodoEntity.kt @Entity data class TodoEntity( @PrimaryKey(autoGenerate = true) val id: Long = 0, val title: String, val content: String ) ``` -------------------------------- ### Configure Kotlin Compilation Options for Device Test Source: https://developer.android.com/kotlin/multiplatform/plugin Configure specific Kotlin compilation options, such as `languageVersion`, for Android compilations like `deviceTest` within the `kotlin` block. ```kotlin // build.gradle.kts kotlin { android { compilations.getByName("deviceTest") { kotlinOptions.languageVersion = "2.0" } } } ``` -------------------------------- ### Execute Non-Result Query with SupportSQLiteDatabase Source: https://developer.android.com/kotlin/multiplatform/sqlite Use this for executing SQL commands that do not return a result set, such as `ALTER TABLE`, with `SupportSQLiteDatabase`. ```kotlin val database: SupportSQLiteDatabase = ... database.execSQL("ALTER TABLE ...") ``` -------------------------------- ### Configure Android target in Kotlin block (build.gradle) Source: https://developer.android.com/kotlin/multiplatform/plugin Configure the `kotlin` block in your module's `build.gradle` to define the Android target, including namespace, SDK versions, and Java compilation support. ```groovy kotlin { android { namespace = "com.example.kmpfirstlib" compileSdk = 33 minSdk = 24 withJava() // enable java compilation support withHostTestBuilder {}.configure {} withDeviceTestBuilder { it.sourceSetTreeName = "test" } compilerOptions.options.jvmTarget.set( org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_1_8 ) } sourceSets { androidMain { dependencies { } } androidHostTest { dependencies { } } androidDeviceTest { dependencies { } } } // ... other targets (JVM, iOS, etc.) ... } ``` -------------------------------- ### Configure Android target in Kotlin block (build.gradle.kts) Source: https://developer.android.com/kotlin/multiplatform/plugin Configure the `kotlin` block in your module's `build.gradle.kts` to define the Android target, including namespace, SDK versions, and Java compilation support. ```kotlin kotlin { android { namespace = "com.example.kmpfirstlib" compileSdk = 33 minSdk = 24 withJava() // enable java compilation support withHostTestBuilder {}.configure {} withDeviceTestBuilder { sourceSetTreeName = "test" } compilerOptions.configure { jvmTarget.set( org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_1_8 ) } } sourceSets { androidMain { dependencies { // Add Android-specific dependencies here } } getByName("androidHostTest") { dependencies { } } getByName("androidDeviceTest") { dependencies { } } } // ... other targets (JVM, iOS, etc.) ... } ```