Hi everyone, does anybody had a problem with delay...
# multiplatform
o
Hi everyone, does anybody had a problem with delay() on ios platform? I have a simple loop: while(true) { println(“log1”) delay(1000) println(“log2") } launched on GlobalScope. On Android it works fine but on ios it doesn’t. Like delay has infinite timeout…
s
You mean that delay never returns?
o
Yes. No “log2” printed on iOS.
s
I’ve seen some never ending tests on iOS. I filed a bug for it here. Perhaps the problem is the
delay
statements. Can you comment issue, thumbs it up and state that you are seeing this problem? https://youtrack.jetbrains.com/issue/KT-37958
l
@Olenyov Kirill Which kotlinx.coroutines version are you using exactly?
o
1.3.4
@louiscad Does it make sense to try 1.3.5?
l
Does it*
o
Yeah, right😅
l
(you can edit messages FYI) Are you using 1.3.4 (no native-mt) with Kotlin 1.3.61 on iOS? When you try, the app is in foreground? Is the app crashing (which triggers the debugger adn freezes the app) or are any UI elements still responding?
o
1.3.4(no native-mt) with Kotlin 1.3.70 App is in foreground, no crash and no any UI problems. Just tried 1.3.5 - the same.
k
delay requires an event loop. you should see an error about this in your stdout.
o
Thanks. Unfortunately I don’t see any error about delay:(. Which error? Where can I read about it? So, I can’t use delay() on ios? What should I do in this case? I just need to have “periodic updates” inside common code..
k
try wrapping it with
runBlocking
somewhere up the call chain
o
Hmm, but we don’t have runBlocking() in kotlinx-coroutines-core-common..
I added “expect customDelay()” method. For Android it is a delay() but for ios runBlocking {delay()} But in this case the UI on ios isn’t responding because…blocking:)
l
@Olenyov Kirill Oh, I recall. On Kotlin/Native, unless you use the
native-mt
artifacts, there's no
Dispatchers.Default
available, so the coroutine launch is never dispatched. Only
runBlocking
is available on Kotlin/Native even without the native-mt artifacts (from native code, not from common code).
o
So the only choice is moving to native-mt to have delay() in common part for both platforms, right?
l
@Olenyov Kirill Or creating your own event loop running on a single thread. If you search for iOS coroutines main thread dispatcher, you'll find an issue where a comment gives an implementation that handles delays and cancellation.
o
Ok. Got it. Thank you!
Hi again! Could you have a look to gist? I think this is maybe workaround for iOS using suspendedCoroutine and platform.darwin.dispatch_after() function. It seems this is a working solution. Any pitfalls? https://gist.github.com/agent10/44583aed07d420191bfdd1b74d58854b
k
it would probably be better to get the current queue and then resume on that queue
o
Hm, I thought that current queue is the same as main queue without “native-mt”. Is it wrong?
l
@Olenyov Kirill You should not need a custom delay implementation. Instead, just have a dispatcher that supports delay, like
Dispatchers.Main
and
Dispatchers.Default
in
native-mt
, or this dispatcher: https://github.com/Kotlin/kotlinx.coroutines/issues/470#issuecomment-440080970 (issue is first link by Googling "ios main thread coroutines dispatcher", you then need to scroll to find the snippet I linked, you can see a great number of positive reactions to it)
o
Hi, thanks. Just tried this solution but it seems something is going wrong. In xcode I get a lot of random errors like SIGABRT or EXC_BAD_ACCESS in random places. May be it’s related with “cancelation” of Jobs..? Or maybe because the solution is quite old(1.5 years..) But with the simple solution(my customDelay) no errors…
Nope, with custom delay I get crashes sometimes too((
l
I'd try with latest native-mt and Kotlin version