You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Gradle多项目与KMM框架:子项目API依赖问题咨询

KMM依赖机制与问题解决方案

一、api(project(":models"))在KMM中的工作机制

在KMM多平台项目中,api(project(":models"))是传递性依赖声明,核心逻辑适配多平台特性:

  1. 依赖传递:依赖client的模块(如iOS/Android应用)能自动使用models的代码,无需重复声明。
  2. 平台自动匹配:Gradle会根据当前构建目标(iOS、Android、JVM等),自动拉取models对应平台源码集的编译产物:
    • Android端(JVM目标):使用models的jvmMain输出
    • iOS端(Native目标):使用models的iosMain输出
  3. 死代码消除(DCE):Kotlin/Native默认开启DCE,仅保留依赖链中被直接/间接引用的代码,未被client或上层应用使用的方法、类型会被编译时剔除,这是你看不到未使用代码的核心原因。

二、iOS端看不到models未使用代码及iOS特定代码的解决方案

1. 调整死代码消除规则

在models的build.gradle.kts中,针对iOS目标配置禁用DCE:

kotlin {
    ios {
        binaries {
            framework {
                // 禁用DCE,保留所有代码
                freeCompilerArgs += "-Xdisable-dead-code-elimination"
            }
        }
    }
}

如果不想完全禁用DCE,可通过显式引用强制保留代码:在models的iosMain中添加公开空对象,让client的iosMain引用它:

// models/iosMain/kotlin/com/example/IOSExports.kt
object IOSExports
// client/iosMain/kotlin/com/example/ClientInit.kt
import com.example.IOSExports

fun initModels() {
    // 显式引用触发DCE保留iosMain所有代码
    IOSExports
}

2. 确保源码集依赖配置正确

检查models的源码集关联,确保iosMain依赖commonMain:

kotlin {
    sourceSets {
        val commonMain by getting
        val iosMain by getting {
            dependsOn(commonMain)
        }
    }
}

同时确认client的iOS目标正确依赖models的iOS产物,避免仅拉取commonMain代码。

三、ModelsUser与第三方User类不关联的解决方案

1. 封装类型转换逻辑

在models中添加扩展函数,实现两个类的双向转换,把转换逻辑封装在models内部:

// models/iosMain/kotlin/com/example/ModelConversions.kt
import com.awesome.framework.User

fun ModelsUser.toAwesomeUser(): User {
    return User(id = this.id, name = this.displayName)
}

fun User.toModelsUser(): ModelsUser {
    return ModelsUser(id = this.userId, displayName = this.userName)
}

2. 抽象通用接口解耦依赖

在models的commonMain中定义通用User接口,让ModelsUser实现它,同时为第三方User添加适配扩展:

// models/commonMain/kotlin/com/example/UserInterface.kt
interface User {
    val id: String
    val name: String
}

// models/commonMain/kotlin/com/example/ModelsUser.kt
data class ModelsUser(override val id: String, override val name: String) : User
// models/iosMain/kotlin/com/example/AwesomeUserAdapter.kt
import com.awesome.framework.User as AwesomeUser

fun AwesomeUser.asUser(): User {
    return ModelsUser(id = this.userId, name = this.userName)
}

这样client只需依赖models的User接口,无需直接接触第三方框架的User类。

3. 调整依赖层级

让models单独依赖AwesomeFramework,client仅依赖models,避免client同时引入AwesomeFramework和AwesomeModels,通过models做中间层封装,隔离第三方依赖。

四、相关学习资源

  • Kotlin官方文档:KMM多平台依赖配置、iOS框架编译选项
  • Kotlin/Native死代码消除规则说明
  • KMM源码集组织与平台特定代码编写指南

内容的提问来源于stack exchange,提问作者edelaney05

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 06:17:44