Kotlin Multiplatform Mobile:Flow<List<*SomeModel*>> 在 iOS 中映射到 Flow<NSArray>
Kotlin Multiplatform Mobile: Flow<List<*SomeModel*>> gets mapped to Flow<NSArray> in iOS
我的共享模块包含存储库 class,它有两个功能 return 包裹在自定义 class 扩展 Flow
称为 CFlow 中的项目列表。
我从 kotlinconf-app and here:
获取了 CFlow
的代码
fun <T> Flow<T>.asCFlow(): CFlow<T> = CFlow(this)
class CFlow<T>(private val origin: Flow<T>) : Flow<T> by origin {
fun watch(block: (T) -> Unit): Closeable {
val job = Job()
onEach {
block(it)
}.launchIn(CoroutineScope(Dispatchers.Main + job))
return object : Closeable {
override fun close() {
job.cancel()
}
}
}
}
存储库示例函数:
fun getData1(): CFlow<List<Profile>>
fun getData2(): CFlow<List<String>>
当我尝试在 iOS swift 代码中调用此函数时,函数的 return 类型被转换为 CFlow<NSArray>
并且 watch 函数内部的类型数组是任意的。
这很奇怪,因为在 kotlinconf-app and here 中都保留了 return 类型的函数,并且它们的代码库中没有涉及转换。
问题:如何让CFlow的类型在XcodeiOS项目中被识别?
Android工作室版本:4.1.1
Kotlin 语言和插件版本:1.4.21
Kotlin Multiplatform Mobile 插件版本:0.2.0
Xcode版本:12.2
这是因为 Objective-C 中没有泛型。数组是对象的有序集合。
因此,在 Kotlin 中使用任何通用集合类型,在转换为 NSArray
时都会丢失其类型
我相信你有以下三种选择:
- 等待直接 Kotlin - Swift 互操作(当前推迟)
- 在 Swift
中转换值
- 不要对集合使用泛型。我个人目前没有使用 Flow wrapper,而是在做这样的事情:
fun observeItems(onChange: (List<Item>) -> Unit) {
items.onEach {
onChange(it)
}.launchIn(coroutineScope)
}
向 iOS
公开处理函数
fun dispose() {
coroutineScope.cancel()
}
像这样消费:
repo.observeItems { items in
...
}
但这肯定是更多的工作,希望这些互操作性问题将在此过程中得到解决
现在编译器无法理解嵌套泛型。作为目前的解决方法,将您的列表包装在数据 class 中,如下所示
data class ProfileResult(val data: List<Profile>)
fun getData1(): CFlow<ProfileResult>
它将在 ios
中为您提供具体类型
我的共享模块包含存储库 class,它有两个功能 return 包裹在自定义 class 扩展 Flow
称为 CFlow 中的项目列表。
我从 kotlinconf-app and here:
获取了CFlow
的代码
fun <T> Flow<T>.asCFlow(): CFlow<T> = CFlow(this)
class CFlow<T>(private val origin: Flow<T>) : Flow<T> by origin {
fun watch(block: (T) -> Unit): Closeable {
val job = Job()
onEach {
block(it)
}.launchIn(CoroutineScope(Dispatchers.Main + job))
return object : Closeable {
override fun close() {
job.cancel()
}
}
}
}
存储库示例函数:
fun getData1(): CFlow<List<Profile>>
fun getData2(): CFlow<List<String>>
当我尝试在 iOS swift 代码中调用此函数时,函数的 return 类型被转换为 CFlow<NSArray>
并且 watch 函数内部的类型数组是任意的。
这很奇怪,因为在 kotlinconf-app and here 中都保留了 return 类型的函数,并且它们的代码库中没有涉及转换。
问题:如何让CFlow的类型在XcodeiOS项目中被识别?
Android工作室版本:4.1.1
Kotlin 语言和插件版本:1.4.21
Kotlin Multiplatform Mobile 插件版本:0.2.0
Xcode版本:12.2
这是因为 Objective-C 中没有泛型。数组是对象的有序集合。
因此,在 Kotlin 中使用任何通用集合类型,在转换为 NSArray
我相信你有以下三种选择:
- 等待直接 Kotlin - Swift 互操作(当前推迟)
- 在 Swift 中转换值
- 不要对集合使用泛型。我个人目前没有使用 Flow wrapper,而是在做这样的事情:
fun observeItems(onChange: (List<Item>) -> Unit) {
items.onEach {
onChange(it)
}.launchIn(coroutineScope)
}
向 iOS
公开处理函数fun dispose() {
coroutineScope.cancel()
}
像这样消费:
repo.observeItems { items in
...
}
但这肯定是更多的工作,希望这些互操作性问题将在此过程中得到解决
现在编译器无法理解嵌套泛型。作为目前的解决方法,将您的列表包装在数据 class 中,如下所示
data class ProfileResult(val data: List<Profile>)
fun getData1(): CFlow<ProfileResult>
它将在 ios
中为您提供具体类型