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

Andy Victors

01/29/2021, 10:28 AM
Hi all, I have a conceptual question. I want to provide a HTTP REST API Wrapper as MPP library. As far as I investigated
ktor
it does not manage async execution for me - the requests API is
suspend
based. So I think I have two options: A) Manage async execution by coroutines inside the common MPP code. From what I recall trying similar things a year ago, there are headaches configuring coroutine contexts for iOS and also some limitations (main thread only). So I am not sure if it all will work at all. B) Or, I can put async logic into platform code. More code but ok. But still, will I be able to call
suspend
marked methods from iOS? I'd like to have thoughts on this topic from more experienced folks.
t

Tijl

01/29/2021, 11:09 AM
not sure what you mean by “ktor does not manage asynch execution”, that’s exactly what it does (in an implementation specific way)
a

Andy Victors

01/29/2021, 11:14 AM
From what I read in documentation, get() and request() methods are all marked as
suspend
so I cannot use them for async calls without wrapping in coroutines or whatever.
t

Tijl

01/29/2021, 11:19 AM
from the ktor homepage:
Asynchronous
Scales as you need it. Using Kotlin coroutines, Ktor is truly asynchronous and highly scalable. Use the power of non-blocking development without the callback nightmare.
am I understanding you right that you want to do something asynchronously but “without wrapping in coroutines or whatever.“?
or do you not mind using it, but you want the consumers of your API not to have to deal with it?
a

Andy Victors

01/29/2021, 11:42 AM
Exactly, I do not want customers of my API to take care about any threading etc, they just need to call a method which will eventually bring result by calling a callback passed as parameter.
t

Tijl

01/29/2021, 11:47 AM
by using
suspend
method they will not to worry about those things. but if you don’t want them to have to call a `suspend`ed method, you can do that for them, for example you can use Deffered and wrap the calls your method do to it in
runBlocking
a

Andy Victors

01/29/2021, 11:57 AM
I cam concerned the most about iOS platform where suspend is not available
t

Tijl

01/29/2021, 11:59 AM
suspend is available on iOS
k

Kris Wong

01/29/2021, 1:40 PM
kotlin/native transforms suspend APIs in the bridging layer to receive a callback instead
however, the only way to get rid of the suspend on your own APIs is to use
runBlocking
or create your own coroutine scope
that said, it doesn't need to be removed
m

Michal Klimczak

01/29/2021, 4:22 PM
Im working on a solution which exposes coroutines to be easily consumable as callbacks or Swift Combine or RxSwift. You can find it here. https://github.com/FutureMind/kmm-ios-suspendwrapper aeound the middle of the next week I should be able to finish an article on that topic
a

Andy Victors

01/29/2021, 8:13 PM
runBlocking() will not solve my problem unfortunately because I want to have an async (non-blocking) call. Also I assume runBlocking() or any similar call needs Coroutine Scope and here we run into trouble on iOS: I do not believe there is an official configuration for this, so anything I will do will be a tinkerer solution, second what is a plain fact: even if you manage to use coroutines on iOS, they only run in Main Thread. I do not want all my network operations to run on network thread, this is weird.
m

Michal Klimczak

01/29/2021, 8:24 PM
Scope can be used in swift code (and hidden as implementation detail if you don't want to expose it too much). And with coroutines-native-mt you get background thread as well, network calls are no longer run on main thread.
k

Kris Wong

01/29/2021, 8:28 PM
the latest Ktor requires the coroutines-native-mt artifact
even before that it didn't make requests on the main thread
m

Michal Klimczak

01/29/2021, 8:53 PM
Oh, didn't know that. Does it have its own thread pool or does it use the native-mt Dispatchers.Default?
I still cannot find any official documentation whether it will work for iOS target
m

Michal Klimczak

01/29/2021, 9:03 PM
You are linking a 2y old article. We are talking cutting edge technology with new stuff coming out every week. Afair coroutines-native-mt came out officially just a few months ago. And it works on ios (kotlin native) but there are some issues so ymmv.
t

Tijl

02/01/2021, 7:39 AM
iOS supports coroutines (including background ones), but as I already pointed out in my first comment, ktor handles the async execution per implementation. AFAIK it does not use coroutines to switch execution to the background in iOS implementation
👍 1
coroutines are just the callback mechanism. so you can do your ktor request from any dispatcher (main, default, or some runblocking somewhere), and ktor will give you the result in that context. it does not actually execute there. of course this does not change that if you want to consume an API from Swift without using the coroutine bridge there, you need to implement your own callback mechanism (or use in existing library that provides something like this) and call a suspended method from there. If you use some thread based solution for this runBlocking should not be a problem obviously. Or you can make some solution based around coroutines that you don’t expose. I would not resolve to googling for articles first, since this is a new tool that is quickly evolving. Official docs here hopefully answer some of your questions https://kotlinlang.org/docs/mobile/concurrency-and-coroutines.html