KMM项目中如何在Swift端正确读取Kotlin共享模块的可变字符数组
问题根源
Kotlin Multiplatform 对 ObjC/Swift 的互操作存在两个默认映射规则,直接导致你当前的转换失败:
- Kotlin 的
Char类型不会映射为 Swift 原生的Character类型,而是会映射为unichar(UInt16的别名,代表16位Unicode字符值) - Kotlin 泛型集合
MutableList<Char>导出到 Swift 后会变为NSArray类型,所有基础类型元素都会被装箱为NSNumber,你直接做as? Character转换会全部失败,compactMap过滤后自然得到空数组。
解决方案
方案1:直接在Swift侧完成类型转换
你只需要先取出NSNumber中存储的unichar值,再通过Unicode标量转成Swift的Character即可:
let reelCharacters = tape.reel.compactMap { element in // 先从NSNumber中取出unichar值 let charValue = element.uint16Value guard let scalar = Unicode.Scalar(charValue) else { return nil } return Character(scalar) }
如果你能确保Kotlin侧的reel存储的都是合法的Unicode字符,可以简化为强制解包的版本:
let reelCharacters = tape.reel.map { Character(Unicode.Scalar($0.uint16Value)!) }
方案2:在Kotlin共享层做适配(适合多处调用的场景)
如果不需要在Swift侧处理原始数值,可以直接在Kotlin侧封装适配属性,减少Swift端的重复代码:
适配为字符数组
val Tape.reelAsCharArray: CharArray get() = reel.toCharArray()
Swift端调用时直接转换即可:
let reelCharacters = tape.reelAsCharArray.map { Character(Unicode.Scalar($0)!) }
适配为字符串(如果业务上可以直接用字符串)
val Tape.reelString: String get() = reel.joinToString("")
Swift端直接获取字符串,需要字符数组时再转:
let reelString = tape.reelString let reelCharacters = Array(reelString)
内容的提问来源于stack exchange,提问作者Travis Baksh
相关产品推荐
相关产品推荐

