KMP中使用swiftklib插件生成的com.player包无法在shared模块iosMain中导入
我明白你遇到的麻烦了——build能正常通过,但就是没法在shared模块的iosMain里导入生成的com.player包,这种看似成功却卡壳的问题确实挺闹心的。咱们一步步来排查解决:
1. 先确认路径配置是否绝对正确
你的swiftklib配置里用了相对路径../iosApp/KmpPlayer/player,Gradle的相对路径是相对于当前build.gradle文件所在目录的(也就是shared模块的根目录)。很可能路径写错了导致插件没找到Swift文件。
可以先加一行打印确认路径是否存在:
swiftklib { create("player") { path = file("../iosApp/KmpPlayer/player") packageName("com.player") // 新增打印,验证路径是否正确 println("Swift source directory path: ${path.absolutePath}") } }
执行./gradlew tasks查看控制台输出,如果路径不存在或者指向错误,调整成正确的相对路径(比如如果iosApp和shared是同级目录,这个路径是对的,但如果目录结构有差异就要改),或者直接用绝对路径测试。
2. 检查Swift类的暴露是否完全符合要求
你的Player类加了@objc public且继承NSObject,方法也加了@objc public,这部分是对的,但要确保:
- Swift文件里没有引用未暴露给Objective-C的类型(比如自定义的Swift结构体没加@objc)
- 文件本身的访问权限没有限制
另外可以去shared模块的build/swiftklib/player目录下看看有没有生成的.klib文件,如果没有,说明swiftklib插件根本没生成库,那肯定导不了。
3. 确保cinterop和swiftklib的配置完全绑定
虽然你的cinterop和swiftklib都用了"player"这个名称,但可以尝试在cinterop配置里手动关联生成的klib,强制绑定:
it.compilations { val main by getting { cinterops { create("player") { // 指定swiftklib生成的库路径 extraOpts("-libraryPath", "${project.buildDir}/swiftklib/player") extraOpts("-linker-option", "-framework", "player") } } } }
这一步能确保cinterop准确找到swiftklib生成的框架。
4. 清理缓存,彻底重新构建
很多时候缓存会导致这种“明明配置对了但不生效”的问题,建议:
- 先执行终端命令:
./gradlew clean build,彻底清理并重新构建所有模块 - 如果还是不行,在Android Studio里点击
File -> Invalidate Caches... -> Invalidate and Restart,重启IDE后再重新构建
5. 检查生成的cinterop头文件,确认包名和类名
去shared模块的build/cinterop/player/iosMain/目录下找到player.h文件,打开看看里面的类是不是被正确映射成了com.player.Player,如果包名不对,那肯定导不了。这时候要检查swiftklib的packageName("com.player")配置有没有写错。
6. 验证版本兼容性
你用的SwiftKlib是0.6.4,而Kotlin已经到了2.0.21,有可能存在版本不兼容的问题。可以尝试升级SwiftKlib到最新稳定版本,然后重新构建,看看能不能解决。
最后,导入的时候可以直接写import com.player.Player试试,有时候只导包名IDE可能不会自动提示,但直接导类名可能会生效。
备注:内容来源于stack exchange,提问作者HT__

