KMM项目nonJS分组配置异常:iOS无法识别Room依赖
KMM多平台Room依赖问题排查与解决方案
一、核心问题定位
你遇到的iOS无法识别Room相关类的本质原因是:Room是AndroidX专属库,官方不支持iOS平台。把Room代码放在包含iOS的nonJS源码集里,iOS模块会尝试依赖Room的Android/JVM二进制,自然无法识别相关类。
二、Gradle配置排查要点
如果暂时不想替换Room,先检查当前nonJS源码集的配置是否存在范围错误:
- 确保
nonJS源码集的Room依赖没有被iOS模块直接依赖:sourceSets { val nonJsMain by creating { dependsOn(commonMain) dependencies { implementation("androidx.room:room-runtime:2.6.1") implementation("androidx.room:room-ktx:2.6.1") } } // Android和Desktop依赖nonJsMain androidMain { dependsOn(nonJsMain) dependencies { kapt("androidx.room:room-compiler:2.6.1") } } desktopMain { dependsOn(nonJsMain) dependencies { kapt("androidx.room:room-compiler:2.6.1") } } // iOS仅依赖commonMain,不依赖nonJsMain iosMain { dependsOn(commonMain) } wasmJsMain { dependsOn(commonMain) } } - 注意:iOS模块不能引入kapt依赖,Room的注解处理器仅支持Android/JVM平台。
三、最优实现方案
方案1:用expect/actual拆分数据层(保留Room)
通过KMM的预期-实际机制,让Android/Desktop用Room,iOS用专属存储方案:
- 在commonMain定义通用接口
interface UserDao { suspend fun getAllUsers(): List<User> suspend fun insertUser(user: User) } expect class DatabaseProvider { fun getUserDao(): UserDao } - 在Android/Desktop实现Room
在nonJsMain(或单独的roomMain源码集)里编写Room数据库和DAO的实现:@Database(entities = [User::class], version = 1) abstract class AppDatabase : RoomDatabase() { abstract fun userDao(): UserDao } actual class DatabaseProvider { actual fun getUserDao(): UserDao { // Android/Desktop的Room初始化逻辑 val db = Room.databaseBuilder(context, AppDatabase::class.java, "app_db").build() return db.userDao() } } - 在iOS实现专属存储
在iosMain里用Core Data或iOS原生SQLite封装实现actual类:actual class DatabaseProvider { actual fun getUserDao(): UserDao { return IOSUserDao() } } class IOSUserDao : UserDao { override suspend fun getAllUsers(): List<User> { // Core Data查询逻辑 return emptyList() } override suspend fun insertUser(user: User) { // Core Data插入逻辑 } }
方案2:替换为多平台兼容的SQLDelight
如果想统一多平台的本地存储实现,推荐用SQLDelight替代Room,它支持Android、iOS、Desktop、WasmJS全平台:
- 配置Gradle依赖
plugins { id("app.cash.sqldelight") version "2.0.1" } sqldelight { databases { create("AppDatabase") { packageName = "com.yourpackage.db" } } } sourceSets { commonMain { dependencies { implementation("app.cash.sqldelight:runtime:2.0.1") implementation("app.cash.sqldelight:coroutines-extensions:2.0.1") } } iosMain { dependencies { implementation("app.cash.sqldelight:native-driver:2.0.1") } } androidMain { dependencies { implementation("app.cash.sqldelight:android-driver:2.0.1") } } desktopMain { dependencies { implementation("app.cash.sqldelight:sqlite-driver:2.0.1") } } wasmJsMain { dependencies { implementation("app.cash.sqldelight:sqlite-wasm-driver:2.0.1") } } } - 编写SQLDelight数据库文件
在commonMain/sqldelight目录下创建.sq文件定义表和查询,SQLDelight会自动生成多平台可用的数据库类。
内容的提问来源于stack exchange,提问作者Abuzaid
相关产品推荐
相关产品推荐

