Hi, I have a question about implementing Kotlin su...
# multiplatform
n
Hi, I have a question about implementing Kotlin suspend functions in Swift with an Kotlin interface. AFAIK, suspend functions are translated as functions with completion handler in the generated ObjC header. In Swift, you then have the option of implementing the functions either with a completion handler or as an async/await function. If I’m using async/await as follows, is it safe? Does the @MainActor annotation work correctly? Is cancellation supported?
Copy code
// Kotlin
interface LoginProvider {
    suspend fun login()
}

// Kotlin
class AndroidLoginProvider: LoginProvider {
    override suspend fun login() { }
}

// Swift
class IOSLoginProvider: LoginProvider {
    @MainActor
    func login() async { }
}


// Kotlin
class AuthenticationRepository {
    [...]

    fun login() = withContext(Dispatchers.IO) {
        loginProvider.login()
    }
}
In the KMP documentation, I only find a clear indication that async/await usage is experimental when suspend functions are called from swift (see https://kotlinlang.org/docs/native-objc-interop.html#suspending-functions). However, this is not the case when a suspend function is implemented via an interface. Also this article https://www.jetbrains.com/help/kotlin-multiplatform-dev/multiplatform-connect-to-apis.html describes only how to implement such apis in the iOS source set in shared. If anyone can provide me with further information or sources, I would be very grateful. Thank you :)
👀 1
j
Would recommend taking a look at using following library https://github.com/rickclephas/KMP-NativeCoroutines
n
Thanks :) but doesn’t it only take care of calling suspend function from swift safely? My question is more about the implementation of suspend functions in swift.
j
Cancellation is not supported calling Kotlin suspend functions as Swift async functions. KMP-NativeCoroutines supports cancellation and addresses other issues. It describes these details in its readme.
n
@Jeff Lockhart thanks for your response, but I don’t think my problem has become completely clear. I call the Swift async function from the Kotlin shared code. I think KMP-NativeCoroutines only provides functions if you want to call a Kotlin suspend function from Swift. Or am I missing something?
j
Oh, I see now. I don't know about the implementation of a Kotlin interface's suspend function in Swift. You would need to test this behavior yourself.
p
@Niklas did you found a solution for this? I am trying to do the same thing. Our platforms (iOS + Android) are using some 3rd party Auth functions for networking which do not have multiplatform support. We need to use these functions in the background thread, so I was thinking about something like:
Copy code
fun initShared(
  getToken: suspend () -> String
)
but it doesnt convert nicely in Swift