KMP 正式支持 SwiftPM:CocoaPods 迁移配置指南

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在你们的工程项目中占比多少了呢?

#Kotlin #KMP #SwiftPM #CocoaPods #AI编程

相关推荐
AFinalStone1 小时前
Android 7系统网络(二)内核层—netfilter_iptables与路由策略
android·网络
吠品2 小时前
Mac定时关机、开机自动化:用shutdown和pmset就够了
android·java·开发语言
2601_9637713717 小时前
Offloading WP-Cron and Securing Ticket Webhooks on Enterprise IT Sites
android
花燃柳卧18 小时前
跨平台路由组件工程源码补充上传
android·flutter·kotlin
apihz18 小时前
随机驾考题目(C 照科一 / 科四 2000+ 题)免费API调用教程
android·java·c语言·开发语言·网络协议·tcp/ip
宸翰18 小时前
uni-app 设置 Android 底部虚拟导航栏背景色
android·前端·uni-app
TechNomad19 小时前
Kotlin类对象与接口详解
android·kotlin
Tisfy19 小时前
iOS:压缩和解压live图(.livp)——百度一刻相册+百度网盘识别支持
ios·百度网盘·livp·live图·一刻相册
Ws_20 小时前
Kotlin Multiplatform day2
kotlin