Search code examples
swiftasync-awaitinterfacekotlin-multiplatformsuspend

Kotlin multiplatform interface suspend function is represented as both async await and completion handler in Swift protocol


As title suggests, I have defined interface in shared KMM module, which I need to implement on iOS side. That interface contains few suspend functions. However, when checking this interface representation in Swift, then each suspend function has both async/await and completionHandler representation in Swift protocol. In other words, I am required to implement both functions despite the fact I need only one (in context of my case I would prefer only completionHandler).

Is there a way to indicate to KMM that I prefer one option over the other instead of having both?


Solution

  • Simple answer is no, there is no way. And that's why: Kotlin doesn't have direct Kotlin <-> Swift interoperability, Kotlin translates code to Objective-C and generate only one completionHandler representation. Then Swift (starting from 5.5) generates two methods from Objective-C code - one with completionHandler and one with async/await. You can read more in official documentation.

    I also suggest you think about your KMM API. Kotlin interfaces and Swift protocols are different and have only partial interoperability, sometimes it is better to provide abstract class instead of interface in your shared module.

    As workaround I recommend you look at Moko-KSwift - this gradle plugin helps generate Swift-friendly API, you can write your own generator and create special Swift helper.

    Or Skie, a Swift-friendly API Generator for Kotlin Multiplatform.