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

Orhan Tozan

04/01/2020, 8:15 AM
Hi, our team have been trying to setup kotlin multiplatform for a month now, and everything seems to be going well from calling mpp code from android. However our iOS dev just build our mpp codebase and says that the compiled code from kotlin mpp is objective c instead of swift, and although our iOS repo swift code swift can call the compiled mpp objective c, it misses some features compared to something that was written in Swift. An example he gave me is that NSMutableArray is being created for MutableList instead of a regular swift typed array. Is there something we miss in our configuration, since I assume most of the people use Swift on iOS side?
a

Artyom Degtyarev [JB]

04/01/2020, 8:21 AM
Hello, @Orhan Tozan! Kotlin/Native has bidirectional interoperability only with C and Objective-C. Swift can be used through Objective-C for now. Consider looking through this doc for additional info. It also has a table with mappings of K/N-Objective-C-Swift concepts
r

ribesg

04/01/2020, 8:35 AM
@Orhan Tozan did something somewhere in the documentation made you think it would be compiled as a Swift framework instead of an Objective-C one? Maybe it’s not clear enough?
o

Orhan Tozan

04/01/2020, 8:44 AM
It's not exactly about the implementation behind it, but more the end result how it looks and is for ios swift code calling mpp code. I'm not an iOS dev, so I dont know how much difference there is for the swift to be used through obj-c compared to pure swift. How much difference is there?
r

ribesg

04/01/2020, 9:23 AM
Swift was made to be compatible with Objective-C, so you can use Objective-C libraries in Swift. Objective-C libraries can be improved for Swift users with things like annotations I think (And Kotlin/Native does that to an extent iirc), but it’s still not a Swift library. I didn’t have issues when I used K/N libraries in Swift apps before, but now I’m just using only Kotlin
o

Orhan Tozan

04/01/2020, 9:38 AM
Ok, thanks. How well supported is using Flow from ios swift side?
r

ribesg

04/01/2020, 9:39 AM
It’s not supported. You can’t use coroutines in Swift nor in Objective-C. (That’s why I’m going 100% Kotlin)
o

Orhan Tozan

04/01/2020, 9:43 AM
I've read that it would work if you use a callback function instead of suspend, isnt that the same for flow?
So something having an extension function on Flow that is non suspending and just accepts a callback function instead
r

ribesg

04/01/2020, 9:43 AM
You can’t see any function marked with the
suspend
keyword in Swift, that’s all. Now see the API of Flow. You could use it with callbacks, yes
o

Orhan Tozan

04/01/2020, 9:50 AM
Im thinking about a mpp common viewmodel that exposes Flow properties. Will this viewmodel be in use of iOS swift code?
s

Sam

04/01/2020, 2:16 PM
Coroutines and K/N are not the best of friends. You can use them if you’re staying only on the main thread but that does make some coroutines features unavailable. There is a special fork of coroutines that uses the worker model to allow multi-threaded coroutines but you’ll have to be careful about freezing objects or K/N will throw an IllegalStateException.
o

Orhan Tozan

04/01/2020, 2:29 PM
Does only staying on the main thread mean that if I perform network requests inside common Kotlin coroutine code, and the method to call for that exposes, besides a suspending method, a method that accepts a good ole callback, that if iOS Swift calls that callback method, the network request would be performed on main thread?
s

Sam

04/01/2020, 2:45 PM
If you’re using ktor, it wraps NSURLSession which performs the request on a background thread. The callback will happen on the main thread which normally isn’t a problem. If your result is a large json document it could tie up the main thread longer than you would want.
o

Orhan Tozan

04/01/2020, 2:54 PM
I understand. So does that mean that
Copy code
withContext(<http://Dispatchers.IO|Dispatchers.IO>) { .. }
does the same as
Copy code
withContext(Dispatchers.Main) { .. }
on iOS?
s

Sam

04/01/2020, 6:10 PM
I did this for now:
Copy code
actual open class CoroutineDispatchProvider {
    actual open val app: CoroutineDispatcher
        get() = applicationDispatcher
    actual open val io: CoroutineDispatcher
        get() = applicationDispatcher //When coroutines can execute on a background thread in native change this to <http://Dispatchers.IO|Dispatchers.IO>
}

internal actual val applicationDispatcher: CoroutineDispatcher = NsQueueDispatcher(dispatch_get_main_queue())

internal class NsQueueDispatcher(
    private val dispatchQueue: dispatch_queue_t
) : CoroutineDispatcher() {
    override fun dispatch(context: CoroutineContext, block: Runnable) {
        dispatch_async(dispatchQueue) {
            block.run()
        }
    }
}
o

Orhan Tozan

04/01/2020, 6:11 PM
What does that do?
r

ribesg

04/02/2020, 8:57 AM
We don’t use
Dispatchers.*
on iOS because it doesn’t work. You need to make a custom “main thread dispatcher”. Here’s ours:
o

Orhan Tozan

04/02/2020, 11:47 AM
Whats the use of creating code for things to run on the main thread if the code is being run on the main thread by default?
r

ribesg

04/02/2020, 12:21 PM
You need a Scope to run coroutines. There is no default.
o

Orhan Tozan

04/02/2020, 12:46 PM
common:
Copy code
val scope = MainScope()
fun foo() {
    scope.launch {
        repeat(1000) {
             delay(100)
             println("")
        }
    }
}
ios swift:
Copy code
foo()
This just works on iOS, doesn it? So whats the difference to do this with your uidispatcher or not
r

ribesg

04/03/2020, 10:04 AM
You tested that on iOS? I’m pretty sure it doesn’t work, unless it changed recently.
MainScope
is a JVM UI thing (Android, JavaFX, Swing)
5 Views