Внедрить базу данных Room в проекте KMM с поддержкой WasmJs

Я создаю проект KMP, который поддерживает Android, iOS, рабочий стол (jvm) и Интернет (wasmJs)... Внутри я реализую комнату для хранения базы данных.

Поскольку WasmJS не поддерживает Room, я создал новый набор исходного кода для Android, iOS и настольных компьютеров и назвал его nonJS.

Вот мой градиент:

kotlin {
    @OptIn(ExperimentalWasmDsl::class)
    wasmJs {
        moduleName = "data"
        browser {
            commonWebpackConfig {
                outputFileName = "composeApp.js"
                devServer = (devServer ?: KotlinWebpackConfig.DevServer()).apply {
                    static = (static ?: mutableListOf()).apply {
                        // Serve sources to debug inside browser
                        add(project.projectDir.path)
                    }
                }
            }
        }
        binaries.executable()
    }

    androidTarget {
        @OptIn(ExperimentalKotlinGradlePluginApi::class)
        compilerOptions {
            jvmTarget.set(JvmTarget.JVM_17)
        }
    }

    listOf(
        iosX64(),
        iosArm64(),
        iosSimulatorArm64()
    ).forEach {
        it.binaries.framework {
            baseName = "data"
            isStatic = true
        }
    }
    jvm("desktop")

    @OptIn(ExperimentalKotlinGradlePluginApi::class)
    applyDefaultHierarchyTemplate {
        // create a new group that
        // depends on `common`
        common {
            // Define group name without
            // `Main` as suffix
            group("nonJs") {
                // Provide which targets would
                // be part of this group
                withAndroidTarget()
                withIos()
                withJvm()
            }
        }
    }

    sourceSets {
        all{
            languageSettings {
                @OptIn(ExperimentalKotlinGradlePluginApi::class)
                compilerOptions{
                    freeCompilerArgs.add("-Xexpect-actual-classes")
                }
            }
        }

        commonMain.dependencies {
            api(project(":domain"))

            implementation(libs.ktor.client.logging)
            implementation(libs.ktor.client.content.negotiation)
        }

        val nonJsMain by getting {
            dependencies {
                api(libs.room.runtime)
                implementation(libs.sqlite.bundled)
            }
        }

        androidMain.dependencies {
            implementation(libs.ktor.client.android)
            implementation(libs.ktor.client.okhttp)

            implementation(libs.paging.room)
        }

        iosMain.dependencies {
            implementation(libs.ktor.client.darwin)
        }

        val desktopMain by getting {
            dependencies {
                implementation(libs.ktor.client.okhttp)
            }
        }

        wasmJsMain.dependencies {
            implementation(libs.ktor.client.js)
        }
    }

    task("testClasses")
}

Затем я создал ожидаемый построитель баз данных для этих платформ в папке, отличной от JS.

База данныхBuilder.kt

expect class DatabaseBuilder() {
    fun databaseBuilder(): RoomDatabase.Builder<AppDatabase>
}

Затем я начал реализовывать реальные файлы

пример DatabaseBuilder.jvm.kt

actual class DatabaseBuilder {
    actual fun databaseBuilder(): RoomDatabase.Builder<AppDatabase> {
        val dbFile = File(System.getProperty("java.io.tmpdir"), "movies_database.db")
        return Room.databaseBuilder<AppDatabase>(
            name = dbFile.absolutePath,
        )
    }
}

Также DatabaseBuilder.iOS.kt

actual class DatabaseBuilder {
    actual fun databaseBuilder(): RoomDatabase.Builder<AppDatabase> {
        val dbFilePath = NSHomeDirectory() + "/movies_database.db"
        return Room.databaseBuilder<AppDatabase>(
            name = dbFilePath,
            factory = { AppDatabase::class.instantiateImpl() }
        )
    }
}

Теперь проблема в следующем:

  • Реализации для Android и настольных компьютеров работают нормально и без проблем.
  • Однако реализация iOS не распознает зависимости RoomDatabase. Фактически он не распознает ни одну из зависимостей или файлов, отличных от JS, как AppDatabase.
  • Нет никакой разницы между Android, Desktop и iOS.

Я думаю, что что-то не так с моим блоком объявлений, отличным от JS.

@OptIn(ExperimentalKotlinGradlePluginApi::class)
applyDefaultHierarchyTemplate {
    // create a new group that
    // depends on `common`
    common {
        // Define group name without
        // `Main` as suffix
        group("nonJs") {
            // Provide which targets would
            // be part of this group
            withAndroidTarget()
            withIos()
            withJvm()
        }
    }
}

Любая помощь с этим?? ИЛИ Есть ли лучший подход к моему проекту??

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
116
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я узнал в чем дело... Как и ожидалось, проблема была в моей иерархии.

Неправильная иерархия:

@OptIn(ExperimentalKotlinGradlePluginApi::class)
applyDefaultHierarchyTemplate {
    common {
        group("nonJs") {
            withAndroidTarget()
            withIos()
            withJvm()
        }
    }
}

Что приводит к этому графику:

Как видите, цель iOSMain не существует... Вместо этого iOS разделена на основные компоненты IosArm64 и IosX64... Вот почему мои классы iOS в папке iOSMain не смогли разрешить никакие зависимости.


Правильная иерархия:

@OptIn(ExperimentalKotlinGradlePluginApi::class)
applyDefaultHierarchyTemplate {
    common {
        group("nonJs") {
            withAndroidTarget()
            withJvm()
            group("ios") {
                withIos()
            }
        }
    }
}

Что приводит к этому графику:

Как вы можете видеть... Здесь Ios создается отдельной группой внутри nonJs... После этого IosArm64 и IosX64 добавляются в "iOSMain". Таким образом, мои классы iOS в папке iOSMain могли разрешать зависимости.

Другие вопросы по теме

Похожие вопросы

Как запросить базу данных комнаты из составного объекта, чтобы получить подробную информацию об элементе
Непонятно, что возвращает комната «Upsert» после успешного обновления
Доступна ли поддержка Room KMP для проекта без общего пользовательского интерфейса?
Получить данные из комнаты в Android
Почему пользовательский интерфейс останавливается при запуске data.clearAllTables() в IO?
Потоки Kotlin не работают должным образом при сборе элементов на экране пользовательского интерфейса с помощью CollectAsState(). Также, может быть, TaskDao.insertTask() не работает?
Как удалить все записи в базе данных и полностью ее инициализировать, включая первичные ключи, при переустановке приложения в Android Room?
Как мне создать поток из базы данных Room, а также предварительно обработать значения?
Миграция базы данных помещений не выполнена должным образом: Причина: java.lang.IllegalStateException:
Правильный сбор потока из помещения