Multiplatform + coroutines + ios threading

Hi, are there some resources or can someone explain me how threading works in iOS?
In all examples which I found there is Dispatchers implementation for ios like this

val main: CoroutineDispatcher = NsQueueDispatcher(dispatch_get_main_queue())
val io: CoroutineDispatcher = NsQueueDispatcher(dispatch_get_main_queue())

but for android it’s

val main: CoroutineDispatcher = Dispatchers.Main
val io: CoroutineDispatcher = Dispatchers.IO

So if i do call like this

 GlobalScope.launch(dispatchers.io) {
            for i 0...1000 {
                println("index $i")
            }
        }

will it run in iOS on main thread or background thread? Based on dispatchers it seems like it’s on main thread.

Here are another options I tested:

  1. Define interface Dao in common code

    interface Dao {
    fun getFoos(): List
    }

  2. Create class in swift

    class DaoImpl: Dao {
    func getFoos(): List {
    return database.query
    }
    }

  3. DaoImpl instance is passed into common module and called like this

    GlobalScope.launch(dispatchers.io) {
    daoInstance.getFoos()
    }

I would expect that 3. will execute daoInstance.getFoos() on background thread but it crashes on iOS because of DB operation on main thread.

I tried also not to use coroutines and rather handle threading in daoImpl like

class DaoImpl: Dao {
        func getFoos(callback: @escaping (List<Foo>) -> Void) {
               DispatchQueue.global(.background).async {
                    let foos = database.query
                    DispatchQueue.global(.background).async {
                           callback(foos)
                    }
               }
         }
    }

and than calling from common module like

daoInstance.getFoos( { foos in
     foos.get...
} )

but this crashes if I tried to access results because of InvalidMutabilityException (because list is created on bg thread but accessed on main)

Is there some recommendated way how to handle threading or any recommendations for this usecase? Thanks

Please consider looking through this discussion in the coroutines GH. Most importantly,

Currently, coroutines are supported only on the main thread.

Thanks. I have checked it already. I just can’t believe that there is no way to use other than main thread on ios. I thought I misunderstood that. How it can be than promoted as shared code between ios/android when there is no support for threading.

I checked few repos with ios examples and they do coroutines + asynchronous calls using ktor. Does it mean that ktor handles threading internally so user of ktor can use only main thread?

How should we do some backgroud work which will work also on ios? It’s common usecase to do something on thread like parsing data, reading from database and then returning results to main thread.

The coroutines are limited by the main thread, but it is changing, see here.
Also, I have to mention here that Kotlin/Native provides instruments to perform tasks on different threads. To learn more about it, I would recommend looking through this document and a presentation, made by CoroutineWorker library creators.

1 Like