If I have a kotlin coroutines Flow exposed in my A...
# multiplatform
s
If I have a kotlin coroutines Flow exposed in my API which is consumed by an iOS client, what options do I have? I was using SKIE but that doesn't have support for Xcode 26 due to lacking support for anything above Kotlin 2.2.10 which is a blocker for me now. I am also aware of https://github.com/rickclephas/KMP-NativeCoroutines but I've never tried it so far. I see they support all latest versions too which is very promising. But is there a way to do anything else to make it at least usable from Swift? It doesn't have to be very pretty, I am just curious of the possibilities here. Even if that means I don't expose a Flow but I do something else for Swift in particular, and keep flow for Android
f
FYI, Xcode 26 is not a requirement on the AppStore yet. Skie need times and the alternatives works. Anyway, it’s not mandatory for using Kotlin from native codes
j
One of the key things that both of those support is cancellation. They're both good solutions....SKIE provides perhaps a more seamless approach but KMP-NativeCoroutines is definitely very good alternative.
There's also https://github.com/rickclephas/KMP-ObservableViewModel btw.....much the same as SKIE's
Observing
f
Yeah! By default, the async are not cancellable
s
Our iOS app started requiring Xcode 26 is what I have understood, but I can definitely get in touch with our iOS developers to understand this better, because it is absolutely not my area of expertise. I am not sure why that was, but we started getting errors that said this: https://kotlinlang.slack.com/archives/C3PQML5NU/p1762346597690099?thread_ts=1762346597.690099&cid=C3PQML5NU which I have (perhaps wrongly) attributed to us building the MP library with an old Kotlin version. For my use case there is just one Flow in the public API, no viewmodels or anything like that so I'm trying to get as minimal of a solution as possible for just this one function. Looks like I'll have to try the other library too then, and take it from there, thanks all!
When you say this: https://kotlinlang.slack.com/archives/C3PQML5NU/p1762358756452539?thread_ts=1762358147.360939&cid=C3PQML5NU How would you even begin to observe the flow though? It gets exposed as a Flow object to Swift through objc, and I haven't been able to find any source online showing how to observe it without using one of the two aforementioned libraries
r
Collecting a Flow from Swift (through the ObjC export) has mainly two challenges: 1. the missing generic type from the
Flow
interface (can be easily resolved by exposing a generic class) 2. using a suspend function and supporting cancellation If you just need to expose a single
Flow
and don’t really care about how it should be consumed in Swift then you can create some basic function. E.g. https://pl.kotl.in/Wmz4CAGm6 Keep in mind that it’s a basic example. You likely want to handle exceptions, must make sure to cancel the collection from Swift, need to pick a CoroutineScope/Dispatcher that makes sense, etc.
s
Right, so this sample keeps the collecting part in kotlin itself and gives tools to cancel for the iOS consumer. That's good to know. Using your library, I would just need the "KMPNativeCoroutinesAsync" part, and to use the
Copy code
do {
  asyncSequence(for...
} catch {
}
function and that should be all there is to it? The docs don't look to have an annotation that needs to be applied to the function which returns flow right?
g
Isn't swift export feature supposed to help us with ?
r
Using your library, I would just need the “KMPNativeCoroutinesAsync” part, and to use the function and that should be all there is to it?
The docs don’t look to have an annotation that needs to be applied to the function which returns flow right?
If you want to use KMP-NativeCoroutines, you’ll need to annotate your Flow function or property with
@NativeCoroutines
. The plugin and Swift helper functions will handle things like exceptions, cancellations mapping, etc.
thank you color 1
Isn’t swift export feature supposed to help us with ?
Yes Swift export is currently under development (incl support for coroutines). But once complete it will indeed provide proper support for coroutines from Swift
d
If you only need to support flows I highly recommend using native coroutines instead of skie the updates is much quicker since its a more focused library only exposing flows/suspend to objective-c. If you need more functionality like exposing sealed classes default arguments and more then skie is really nice but blocks you from updating a lot of times since it is a much broader and complex tool.
Also if it literally is only 1 flow then maybe writing the conversion yourself and not relying on a library is also a good solution. Since then if a kotlin update breaks it you fix it at that moment.
s
Trying KMPNC and so far I am liking it, so far it's looking like what I needed. I am indeed missing exhaustive when statements on a sealed interface we had, but I mean that's a small price to pay.
Rick, does your library have a way for Swift to call functions which expect a closure which is suspending itself? Something like
fun foo(suspend block: () -> Unit)
Or what should one do in such a scenario?
r
Hey. No unfortunately the Swift to Kotlin cases aren’t supported. (and since Swift export is in the works it won’t be supported in the future either)