KMP 模块里 CocoaPods 如何依赖迁到 Swift Package Manager?
页面里的入口是 Junie + Kotlin AI Skill,但迁移本身仍然要回到 Gradle、Xcode 和 Kotlin imports 这几个具体文件。
SwiftPM import 现在还是 Alpha,示例要求 KMP Gradle 插件使用 2.4.0-RC2。项目里如果已经通过 CocoaPods 接了 Firebase、Google Maps 这类 iOS SDK,这个迁移就不只是替换包管理器,还会影响 iOS 侧构建方式。

先看边界
这次说的是"在 KMP 模块里引入 SwiftPM 依赖"。也就是说,Kotlin 代码可以通过 SwiftPM import 调用 Objective-C API,Kotlin/Native 编译和 framework 链接时,Gradle 插件会把 SwiftPM 依赖需要的机器码带上。
这个功能不等于把使用 SwiftPM import 的 KMP 模块再导出成一个 Swift package。文档里明确写了,这个场景还不支持,可能不能正常工作。如果你的交付方式是把 shared 模块发布成 Swift package 给 iOS 团队消费,这条限制要先确认。
另一个边界是动态 Kotlin/Native framework。遇到 Undefined symbols for architecture ...、dyld: Symbol not found,或者同一个 Objective-C class 在两个 binary 里重复实现时,文档给的通用处理方式是把 framework 改成静态:
bash
kotlin {
listOf(
iosArm64(),
iosSimulatorArm64()
).forEach { iosTarget ->
iosTarget.binaries.framework {
baseName = "Shared"
isStatic = true
}
}
}
这个点和 CocoaPods 迁移关系很近。以前很多项目会把 framework 配在 cocoapods.framework {} 里,迁到 SwiftPM 后,这部分要移到 Apple target 的 binaries.framework {} 下。

Junie 和 Skill
Junie 的使用方式比较直接。先安装 CLI,然后登录 JetBrains 账号,或者配置外部 LLM:
bash
curl -fsSL https://junie.jetbrains.com/install.sh | bash
junie
项目目录下安装 Kotlin AI Skill:
bash
npx skills add Kotlin/kotlin-agent-skills
这个命令要求 npm 不低于 5.2.0。交互里选择 kotlin-tooling-cocoapods-spm-migration,agent 选择 Junie,scope 选择 Project,这样 Skill 只落在当前项目里。
之后在项目根目录启动 Junie:
bash
junie
输入迁移任务:
bash
Migrate <project-name> from CocoaPods to SwiftPM
Junie 会识别刚安装的 Skill,然后开始检查项目。开始前要保证项目已经在 Git 里,因为后面要靠 diff 看它到底改了哪些文件。AI 工具会改对一部分,也可能把 Xcode 工程、Podfile 或 imports 改偏,不能把生成结果当成最终结论。

Gradle 变化
SwiftPM import 要求 Kotlin Multiplatform Gradle plugin 使用 2.4.0-RC2。如果项目用 Version Catalog,版本入口大概是这样:
bash
[versions]
kotlin = "2.4.0-RC2"
[plugins]
kotlin-multiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" }
依赖迁移时不要一开始就删 CocoaPods。文档里的顺序是先加 swiftPMDependencies {},让 SwiftPM 和 CocoaPods 依赖短时间并存,等 SwiftPM import 能解析、Kotlin 代码也能编译,再清理 CocoaPods。
以 FirebaseAnalytics 为例,build.gradle.kts 里会多一个 Swift package 声明:
bash
kotlin {
iosArm64()
iosSimulatorArm64()
swiftPMDependencies {
swiftPackage(
url = url("https://github.com/firebase/firebase-ios-sdk.git"),
version = from("12.5.0"),
products = listOf(product("FirebaseAnalytics")),
)
}
cocoapods {
pod("FirebaseAnalytics") {
version = "12.5.0"
}
}
}
如果 Swift package 里的 Clang module 名称和 product 名称不一致,就不能只写 product。discoverClangModulesImplicitly = false 之后,需要用 importedClangModules 明确列出来。FirebaseFirestore 的 Objective-C API 就在文档示例里的 FirebaseFirestoreInternal module 中。
bash
kotlin {
swiftPMDependencies {
discoverClangModulesImplicitly = false
swiftPackage(
url = url("https://github.com/firebase/firebase-ios-sdk.git"),
version = from("12.5.0"),
products = listOf(
product("FirebaseAnalytics"),
product("FirebaseFirestore"),
),
importedClangModules = listOf(
"FirebaseAnalytics",
"FirebaseFirestoreInternal",
),
)
}
}
多 Apple target 项目还要看平台约束。比如 Google Maps SDK 当前只支持 iOS target,项目里如果同时有 iosArm64() 和 macosArm64(),产品声明要限制到 iOS:
bash
kotlin {
iosArm64()
iosSimulatorArm64()
macosArm64()
swiftPMDependencies {
swiftPackage(
url = url("https://github.com/googlemaps/ios-maps-sdk.git"),
version = exact("10.3.0"),
products = listOf(
product("GoogleMaps", platforms = setOf(iOS()))
)
)
}
}
最后
KMP在你们的工程项目中占比多少了呢?