Kotlin Multiplatform Mobile:Flow<List<*SomeModel*>> 被映射到 iOS 中的 Flow<NSArray>
Posted
技术标签:
【中文标题】Kotlin Multiplatform Mobile:Flow<List<*SomeModel*>> 被映射到 iOS 中的 Flow<NSArray>【英文标题】:Kotlin Multiplatform Mobile: Flow<List<*SomeModel*>> gets mapped to Flow<NSArray> in iOS 【发布时间】:2021-03-24 15:25:33 【问题描述】:我的共享模块包含 Repository 类,该类具有两个函数,它们返回包装在自定义类中的项目列表,该自定义类扩展名为 CFlow 的 Flow
。
我从kotlinconf-app 和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 代码中调用此函数时,函数的返回类型会转换为 CFlow<NSArray>
,并且在 watch 函数内部,数组的类型是 Any。
这很奇怪,因为在 kotlinconf-app 和 here 中,函数的返回类型都被保留了,并且它们的代码库中不涉及强制转换。
问题:如何让 Xcode iOS 项目中知道 CFlow 的类型?
android Studio 版本:4.1.1
Kotlin 语言和插件版本:1.4.21
Kotlin Multiplatform Mobile 插件版本:0.2.0
Xcode 版本:12.2
【问题讨论】:
【参考方案1】:现在编译器无法理解嵌套泛型。作为目前的解决方法,将您的列表包装在这样的数据类中
data class ProfileResult(val data: List<Profile>)
fun getData1(): CFlow<ProfileResult>
它会给你一个具体的 ios 类型
【讨论】:
感谢您的回答。它有助于使事情更清晰【参考方案2】:这是因为 Objective-C 中没有泛型。数组是对象的有序集合。
所以在 Kotlin 中使用任何通用集合类型,在转换为 NSArray
时都会丢失它的类型
我相信你在这里有三个选择:
-
等待直接 Kotlin - Swift 互操作(目前已推迟)
在 Swift 中转换值
不要在集合中使用泛型。我个人目前没有使用 Flow 包装器,而是在做这样的事情:
fun observeItems(onChange: (List<Item>) -> Unit)
items.onEach
onChange(it)
.launchIn(coroutineScope)
向 iOS 公开一个 dispose 函数
fun dispose()
coroutineScope.cancel()
然后像这样消费:
repo.observeItems items in
...
但这肯定是更多的工作,希望这些互操作问题将在此过程中得到解决
【讨论】:
感谢您的回答。它有助于使事情更清晰以上是关于Kotlin Multiplatform Mobile:Flow<List<*SomeModel*>> 被映射到 iOS 中的 Flow<NSArray>的主要内容,如果未能解决你的问题,请参考以下文章
Kotlin-multiplatform:如何执行 iOS 单元测试
在 kotlin-multiplatform 上生成 UUID?
Kotlin Multiplatform 项目包含 cocoapod 依赖项
如何使用 Kotlin-Multiplatform 在 iOS 应用程序的后台线程中运行任务?