KMM на iOS: нет цикла событий. Используйте runBlocking {…}, чтобы запустить его
Я пытаюсь использовать в
Kotlin Multiplatform
проект. Я ни в чем не разбираюсь.
Я пытаюсь вызвать эту функцию
fun startFlow {
coroutineScope.launch {
withContext(defaultDispatcher) {
myFlow.collect { next -> onNext(next) }
}
}
}
coroutineScope
на этом
val defaultScope: CoroutineScope = object : CoroutineScope {
override val coroutineContext: CoroutineContext
get() = SupervisorJob() + Dispatchers.Default
}
Это не единственный вызов, который вызывает у меня эту проблему, фактически все обращения к
coroutines
похоже, не работает с этой ошибкой:
kotlin.IllegalStateException: There is no event loop. Use runBlocking { ... } to start one.
Вот как я импортирую библиотеку
val commonMain by getting {
dependencies {
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.4.3")
}
}
я использую
Kotlin
1.4.31. Эта проблема присутствует только в
iOS
,
Android
работает безупречно.
Я не понимаю, упускаю ли я что-то.
3 ответа
для iOS вам необходимо использовать сопрограммы с суффиксом "native-mt", подробнее здесь
поэтому замените свой импорт на
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.4.3-native-mt")
Если вы используете последнюю версию KMM, и указанная выше библиотека native-mt не работает, то вот решение для вас:
Перейти к вашей
gradle.properties
В
#kotlin
разделе (или на новой строке) добавьте следующую строкуkotlin.native.binary.memoryModel=experimental
Синхронизируйте файлы Gradle
Это должно включить экспериментальную модель памяти для Kotlin, и ваш проект должен начать работать на iOS.
Вы также можете использовать обычный
coroutines
библиотека, но тогда вам нужно создать пользовательский CoroutineDispatcher , которая отправляет задачи на mainRunLoop, например:
object NSLooperDispatcher: CoroutineDispatcher() {
override fun dispatch(context: CoroutineContext, block: Runnable) {
NSRunLoop.mainRunLoop.performBlock {
block.run()
}
}
}
// use custom dispatcher
withContext(NSLooperDispatcher) {
myFlow.collect { next -> onNext(next) }
}
Есть проблемы с переключением потоков, которые
native-mt
ветвь сопрограмм подробно описана, поэтому ее использование может быть хорошей идеей. В противном случае вы ограничены одним основным потоком.