首页 > 解决方案 > 从 iOS 收听 Kotlin 协程流程

问题描述

我已经设置了一个 Kotlin Multiplatform 项目并附加了一个SQLDelight数据库。它的所有设置和运行都正确,因为我已经使用以下方法在 android 端对其进行了测试:

常见的主要:

    val backgroundColorFlow: Flow<Color> =
            dbQuery.getColorWithId(BGColor.id)
                    .asFlow()
                    .mapToOneNotNull()

在 Android 项目MainActivity.kt中使用:

database.backgroundColorFlow.onEach { setBackgroundColor(it.hex) }.launchIn(lifecycleScope)

但是当尝试在 iOS 项目应用程序委托中访问相同的调用时,我得到以下选项,我不确定如何使用它们或将它们转换为我的BGColor对象:

database.backgroundColorFlow.collect(collector: T##Kotlinx_coroutines_coreFlowCollector, completionHandler: (KotlinUnit?, Error?) -> Void)

谁能帮助我如何使用它?

标签: swiftkotlin-coroutineskotlin-multiplatform

解决方案


所以这是通过创建一个流助手来解决的:

import io.ktor.utils.io.core.Closeable
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*

fun <T> Flow<T>.asCommonFlow(): CommonFlow<T> = CommonFlow(this)
class CommonFlow<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()
            }
        }
    }
}

我的backgroundColorFlowvar 更新如下以利用此助手:

    val backgroundColorFlow: CommonFlow<BGColor> =
            dbQuery.getColorWithId(BGColor.id)
                    .asFlow()
                    .mapToOneNotNull()
                    .map { BGColor(it.name) }
                    .asCommonFlow()

然后我的 swift 工作如下:

database.backgroundColorFlow.watch { color in
            guard let colorHex = color?.hex else {
                return
            }
            self.colorBehaviourSubject.onNext(colorHex)
        }

和 android 像这样:

database.backgroundColorFlow.watch { setBackgroundColor(it.hex) }

希望这可以帮助遇到此问题的任何人。我想将 CommonFlow 类转换为 Flow 的扩展,但没有专业知识 atm 所以如果有的话,恕我直言,这将是一个更好的解决方案


推荐阅读