Trying to see how Swift's new async/await could be...
# kotlin-native
j
Trying to see how Swift's new async/await could be hooked in to shared KMM code and noticed by chance that following (in thread) works was was sort of curious why 🙂 ...
👀 3
if I have something like this in shared code (seems it has to be both suspend function AND provide success/completion handler like this)
Copy code
suspend fun fetchPeople(success:  (List<Assignment>)  -> Unit) {
	val people = peopleInSpaceApi.fetchPeople().people
	success(people)
}
Then XCode gives "consider using asynchronous alternative function" prompt and can then invoke like this...it blocks then until completion handler invoked.
Copy code
async {
    do {
        print("before")
        try await repository.fetchPeople(success: { people in
            print(people)
            self.people = people
        })
        print("after")
    }
    catch {
        print("exception")
    }
}
I think this is based somehow on functionality Swift is providing to allow invoking "legacy" Objective C etc functions that use completion handlers....
btw following is the signature for the generated wrapper function
Copy code
(void)fetchPeopleSuccess:(void (^)(NSArray<CommonAssignment *> *))success completionHandler:(void (^)(CommonKotlinUnit * _Nullable, NSError * _Nullable))completionHandler __attribute__((swift_name("fetchPeople(success:completionHandler:)")));
k
Looks like we're getting async await support for free because of their obj c interop?🙂 Too bad it requires iOS 15...😔
j
The bigger unknown I think is around supporting cancellation....I can hook in to that on the Swift side of things (using
withTaskCancellationHandler
) but not sure if/how we can get access to a cancellable job corresponding to the suspend function (to allow propagating the cancellation)....
Also, a bit "clunky" above (and probably not realistic usage) that suspend function also needs to be passed a success handler
k
If you think in terms of callbacks, it makes sense that there's a success callback to return data. Makes me wonder if they added support for other callbacks... (Cancel and error)
j
well, I guess it depends....you can use that callback mechanism right now (and in fact have to) if not using suspend functions.....with Kotlin 1.4's support for invoking suspend functions directly then you should be able to return data "as normal" and then that gets mapped by Kotlin/Native on Swift/Obj C side to completion handler.....also, if you add
@Throws
annotation to that suspend function then you also get error callback as well
h
To be honest, calling a suspend function with a callback looks strange to me. Either use suspend and return the result "later" or use the callback without suspend at all.
👍 1
j
yeah, exactly....that was my point above too ("...probably not realistic usage") .....was more curious how that ended up then having the particular signature that XCode recognized as being callable as
async
function....
👍 1
btw, re. cancellation, I've tried using non-suspend function in shared code, launching coroutine in it, caching/exposing the returned job, and then tried to use it to cancel coroutine from Swift (from
withTaskCancellationHandler
)....but running in to a few issues there still.
some notes on exploration so far (as mentioned, more questions than answers!) https://johnoreilly.dev/posts/swift_async_await_kotlin_coroutines/
🎉 3
h
j
Just saw that and not clear yet implications it has....at least for stuff I've tried so far. btw talking to @Rick Clephas atm about code he's been adding to https://github.com/rickclephas/KMP-NativeCoroutines/tree/feature/swift-async-await ....looks very promising
r
Yeah the objc interop for async/await is cool but not very useful IMO as it doesn’t support cancellation. Which might be obvious if the function is a normal callback function from an objc library but I guess can be confusing in the case of Kotlin coroutines. Currently the suspend function can be called as an async function in Swift due to the interop with objc callbacks. But in the end it’s still the callback function being used without cancellation support.