如何在 KMM(kotlin 本机)共享模块中读取 Swift 框架库中生成的对象数组
Posted
技术标签:
【中文标题】如何在 KMM(kotlin 本机)共享模块中读取 Swift 框架库中生成的对象数组【英文标题】:How to read an array of objectes generated in a Swift framework library, in a KMM (kotlin native) shared module 【发布时间】:2021-06-10 05:00:13 【问题描述】:我正在开发一个 KMM 应用程序。共享模块有一个帮助类,它依赖于 android 部分和 ios 部分的不同本地库。这是通过已知的“预期/实际”模式实现的。
如前所述,iOS 实际类使用了一个 iOS 框架,它执行一些计算并返回一个对象数组。创建对象列表的 ios 框架可以正常工作(通过单元测试进行了测试)。下面是一个简化的示例。
这是数组内对象的类:
public class ChildNodeIos: NSObject
public let content:String
public let isTextNode:Bool
public init(content:String,isTextNode:Bool=false)
self.content=content
self.isTextNode=isTextNode
iOS 端返回对象列表的帮助器类是这样的:
@objc public class IOSCoolHelper: NSObject
@objc public func getChildNodes(message: String) -> [ChildNodeIos]
//build the array of child nodes here and return them
在 kotlin 共享模块中,在 iOS 预期类中,函数调用如下:
@Serializable
data class ChildNodeKN(val content :String,val isTextNode :Boolean=false)
import com.mydomain.iosframeworks.IosCoolHelper
actual class CoolHelper actual constructor(private val someStuff: String) : ICoolHelper
actual override fun getChildNodes(message: String): List<ChildNodeKN>
val iosHelper= IOSCoolHelper()
val swiftarray:List<ChildNodeIos> = iosHelper.getChildNodes(message)
//I was expecting to do something like that but it does not work (the content of "array is always empty"):
val kotlinList:List<ChildNodeKN> = swiftarray as List<ChildNodeIos>
return kotlinList
或者,如果 swift 对象列表不能直接转换为等效的 kotlin 对象列表,我希望能够遍历 swift 列表并将其转换为 kotlin 列表,如下所示:
val kotlinList=mutableListOf<ChildNodeKN>()
swiftArray.foreach
kotlinList.add(ChildNodeKN(it.content,it.isTextNode))
但同样,swift Array 的内容是空的。做了很多测试(我现在无法重现它们),我设法访问了数组中的一些东西,但它不是 ChildNodeIos 类型的对象,也不是我在 kotlin 端读不到的东西。
好吧,问题是,如何在 kotlin 端接收 iOS 端生成的内部或多或少复杂对象的列表?
我不得不说,这个 swift helper 类还有许多其他返回原始值(字符串、布尔值或 int)的函数,而且效果很好。
我想一个解决方法是使用一个包含对象的数组,从 Swift 端返回一个包含原始类型和二维的数组,但如果可能的话,我想使用一个对象数组。
感谢您的帮助
【问题讨论】:
【参考方案1】:我自己设法找到了解决方案。问题在于列表中包含的对象的 Swift 类的声明。我忘记了类属性的@objc 声明,因为如果那样我就无法读取返回数组中的对象。
公共类 ChildNodeIos: NSObject
@objc public let content:String
@objc public let isTextNode:Bool
public init(content:String,isTextNode:Bool=false)
self.content=content
self.isTextNode=isTextNode
然后,在 Kotlin 方面,我没有实现将其直接转换为列表,但是使用 foreach 循环很容易在 Kotlin 对象中编写 iOS 对象:
【讨论】:
以上是关于如何在 KMM(kotlin 本机)共享模块中读取 Swift 框架库中生成的对象数组的主要内容,如果未能解决你的问题,请参考以下文章
如何在 iOS 项目中添加两个或多个 kotlin 原生模块
KMM(Kotlin Multiplatform Mobile)环境搭建