https://kotlinlang.org logo
#multiplatform
Title
# multiplatform
f

Ferran

11/13/2020, 11:29 AM
do you know if
SharedFlow
is available from
org.jetbrains.kotlinx:kotlinx-coroutines-core:1.4.1
? if not, which dependency shall I add for the
commonMain
sourceset?
👀 1
👌 2
which scope should I pass to the
launchIn
when invoked from iOS?
r

ribesg

11/13/2020, 12:55 PM
The scope you want to run your coroutine in
f

Ferran

11/13/2020, 12:57 PM
as far as I know the only available scope from iOS is provided by
runBlocking
but that doesn’t work. I’ve tried a custom implementation that doesn’t work either:
Copy code
internal actual fun CustomMainScope(): CoroutineScope = CustomMainScopeImpl()
internal class CustomMainScopeImpl : CoroutineScope {
    private val dispatcher = MainDispatcher()
    private val job = Job()
    private val exceptionHandler = CoroutineExceptionHandler { _, throwable ->
        println("${throwable.message}: ${throwable.cause}")
    }
    override val coroutineContext: CoroutineContext
        get() = dispatcher + job + exceptionHandler
}
private class MainDispatcher : CoroutineDispatcher() {
    @Suppress("TooGenericExceptionCaught")
    override fun dispatch(context: CoroutineContext, block: Runnable) {
        dispatch_async(dispatch_get_main_queue()) {
            try {
                block.run()
            } catch (err: Throwable) {
                throw err
            }
        }
    }
}
Maybe I’m missing something very obvious here :S
r

ribesg

11/13/2020, 1:01 PM
Uh no you have all the usual scope. You can try
MainScope()
to run it on the UI thread
f

Ferran

11/13/2020, 1:02 PM
I’m not sure how a hot stream through a StateFlow can work on the main thread without blocking the entire application though :S
but will feedback once I try it
r

ribesg

11/13/2020, 1:03 PM
You can make a scope from a new thread with something like
CoroutineScope(newSingleThreadContext("Test"))
I would recommend always adding a
CoroutineExceptionHandler
to catch all uncaught exceptions in coroutines and deal with them properly
I use this in all my Presenters
Copy code
@Suppress("FunctionName")
fun ErrorLoggingMainScope(log: Log, ignoreCancellationException: Boolean = true): CoroutineScope =
    MainScope() + CoroutineExceptionHandler { _, e ->
        if (ignoreCancellationException && e is CancellationException) return@CoroutineExceptionHandler
        log.error("Uncaught error in coroutine", e)
    }
Log
being my own thing which logs (lol) and also sends errors to Bugsnag
f

Ferran

11/13/2020, 1:04 PM
yup but
newSingleThreadContext
is not part of coroutines 1.4.1, is part of the
-native-mt
and as far as I know the mt branch version does not support StateFlow yet
r

ribesg

11/13/2020, 1:05 PM
Oh, yeah. You can’t do multithreaded coroutines outside the native-mt branch obviously, you just have the main thread
f

Ferran

11/13/2020, 1:05 PM
ok so on 1.4.x state flow is broken from iOS because it will completely block the main thread, is that correct?
r

ribesg

11/13/2020, 1:06 PM
I would not recommend frankensteining a dispatcher for outside the main thread yourself
Probably, I don’t use non-mt coroutines. I’m on 1.3.9 waiting for things to happen.
f

Ferran

11/13/2020, 1:07 PM
he yup, oki
r

ribesg

11/13/2020, 1:07 PM
I can’t wait for stateflow either 🙂
l

louiscad

11/13/2020, 1:10 PM
@Ferran If you need to use coroutines only on the main thread, you can use that dispatcher until Kotlin/Native gets a new memory model and
Dispatchers.Main
gets working on iOS (or there's a newer
native-mt
version, in the meantine): https://github.com/Kotlin/kotlinx.coroutines/issues/470#issuecomment-440080970
f

Ferran

11/13/2020, 1:12 PM
I’ll give it a go, thanks @louiscad!
👋 @Tobi 😄
😄 1
👋 1
5 Views