1

我的共享模块包含 Repository 类,该类具有两个函数,它们返回包装在Flow名为 CFlow 的自定义类中的项目列表。

CFlowkotlinconf-app这里获取了代码:

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这里都保留了函数的返回类型,并且它们的代码库中不涉及强制转换。

问题:如何让 Xcode iOS 项目中知道 CFlow 的类型?

安卓工作室版本:4.1.1

Kotlin 语言和插件版本:1.4.21

Kotlin Multiplatform Mobile 插件版本:0.2.0

Xcode 版本:12.2

截图1

截图2

4

2 回答 2

3

现在编译器无法理解嵌套泛型。作为现在的解决方法,将您的列表包装在这样的数据类中

data class ProfileResult(val data: List<Profile>)

fun getData1(): CFlow<ProfileResult>

它会给你一个具体的 ios 类型

于 2020-12-21T10:23:30.863 回答
2

这是因为 Objective-C 中没有泛型。数组是对象的有序集合。

因此,在 Kotlin 中使用任何通用集合类型,在转换为时都会丢失它的类型NSArray

我相信你在这里有三个选择:

  1. 等待直接 Kotlin - Swift 互操作(目前已推迟)
  2. 在 Swift 中转换值
  3. 不要将泛型与集合一起使用。我个人目前没有使用 Flow 包装器并做这样的事情:
fun observeItems(onChange: (List<Item>) -> Unit) {
        items.onEach {
            onChange(it)
        }.launchIn(coroutineScope)
    }

向 iOS 公开 dispose 函数

fun dispose() {
    coroutineScope.cancel()
}

像这样消费:

repo.observeItems { items in
    ...
}

但肯定这是更多的工作,希望这些互操作问题将在此过程中得到解决

于 2020-12-14T06:50:31.900 回答