@OptIn(InternalCoroutinesApi::class) private object IosMainDispatcher : CoroutineDispatcher(), Delay { override fun dispatch(context: CoroutineContext, block: Runnable) { dispatch_async(dispatch_get_main_queue()) { block.run() } } @InternalCoroutinesApi override fun scheduleResumeAfterDelay(timeMillis: Long, continuation: CancellableContinuation) { dispatch_after(dispatch_time(DISPATCH_TIME_NOW, timeMillis * 1_000_000), dispatch_get_main_queue()) { try { with(continuation) { resumeUndispatched(Unit) } } catch (err: Throwable) { throw err } } } @InternalCoroutinesApi override fun invokeOnTimeout(timeMillis: Long, block: Runnable): DisposableHandle { val handle = object : DisposableHandle { var disposed = false private set override fun dispose() { disposed = true } } dispatch_after(dispatch_time(DISPATCH_TIME_NOW, timeMillis * 1_000_000), dispatch_get_main_queue()) { try { if (!handle.disposed) { block.run() } } catch (err: Throwable) { throw err } } return handle } }