如何在KMM的iOS主模块Kotlin代码中调用同模块的Swift类
如何在KMM的iOS主模块Kotlin代码中调用同模块的Swift类
嗨,我来帮你搞定这个KMM里Kotlin找不到Swift类的问题!你现在遇到的「unresolved Reference Employee」错误,核心是Kotlin/Native没法直接识别Swift代码,得通过Objective-C桥接来打通,虽然你的Swift类已经做了基础的ObjC兼容配置,但还差几步关键操作~
先确认Swift类的ObjC兼容基础(你已经做对啦)
你的Swift类写法完全符合ObjC兼容要求:
- 继承了
NSObject - 用
@objc修饰了类、属性、初始化方法和实例方法
这是Swift能被Objective-C(进而被Kotlin)访问的前提,这部分不用改。
给Xcode模块做个关键配置
打开你的iOS主模块的Xcode项目,找到Build Settings:
- 搜索「Defines Module」,把它改成
YES,这样Xcode会自动生成这个模块的Objective-C接口头文件,Kotlin才能通过这个接口找到你的Swift类。 - 记一下你的「Product Module Name」(就是iOS主模块的名称,比如你的App叫MyKMMApp,这里就是MyKMMApp),后面要用到。
让Kotlin能“看到”iOS模块的Swift类
这里分两种情况,看你的Kotlin代码放在哪里:
情况1:Kotlin代码在KMM项目的iosMain源集(属于shared模块的iOS部分)
- 先在
src/iosMain/nativeInterop/cinterop目录下新建一个.def文件,比如叫iosapp.def,内容就写:
把language = Objective-C modules = [你的iOS主模块名称][你的iOS主模块名称]替换成刚才记的「Product Module Name」。 - 打开项目根目录的
build.gradle.kts(或build.gradle),找到iOS目标的配置,添加cinterop的设置:ios { binaries { framework { baseName = "shared" } } cinterops { create("iosapp") { // 这个名称要和你刚才建的.def文件名完全一致 defFile = file("src/iosMain/nativeInterop/cinterop/iosapp.def") } } } - 同步一下Gradle配置,让新的cinterop生效。
情况2:Kotlin代码直接在Xcode的iOS主模块Target里
这种情况更简单:
- 先确认Kotlin文件已经被加入到iOS主模块的Target中:选中Kotlin文件,看右侧Xcode Inspector里的「Target Membership」,确保勾选了你的iOS主模块。
- 在Kotlin代码开头导入iOS模块的Objective-C接口:
import platform.[你的iOS主模块名称].*
最后修复Kotlin代码里的小问题
现在你应该能在Kotlin里找到Employee类了,但还有个小坑:你的Swift类只有带参数的初始化方法(init(name: String, age: Int)),没有无参构造,所以Kotlin里val emp = Employee()会报错,得改成带参数的写法:
// 记得导入对应的模块哦 import platform.[你的iOS主模块名称].* class Caller { val emp = Employee(name = "Remon", age = 30) // 传入name和age参数 actual fun description(): String { return emp.description() ?: "" // 调用Swift类的description方法,加个空安全处理更稳妥 } }
做完这些操作后,重新编译项目,那个「unresolved Reference Employee」的错误应该就消失啦!
备注:内容来源于stack exchange,提问作者Remon Shehatta
相关产品推荐
相关产品推荐

