Piotr Prus
10/25/2023, 11:17 AMfun initKoinIos(buildEnvironment: BuildEnvironment, getAccessToken: suspend () -> String): KoinApplication =
initKoin(
appModules = listOf(),
buildEnvironment = buildEnvironment,
getAccessToken = getAccessToken
)
but it translate to KotlinSuspendFunction in objC/Swift and I have no idea how to use it there.
According to https://kotlinlang.org/docs/native-objc-interop.html#mappings it should be async/completionHandler, but I guess it does not work for high order functions??
I am thinking of making an interface with this suspend function, but wanted to ask about your opinion.Ciaran Sloan
10/25/2023, 11:46 AMinterface TokenProvider {
fun getToken(callback: (String) -> Unit)
}
Then pass an implementation of this interface into koin, instead of your higher order function.
Then when you need to use this inside a coroutine in your KMP code, wrap the TokenProvider::getToken
inside a suspendCancellableCoroutine
. There may be a way to do what your wanting to do, but personally I prefer to abstract away the complexity of coroutines from the underlying platforms.Piotr Prus
10/26/2023, 6:10 AMCiaran Sloan
10/26/2023, 8:43 AMTokenProvider
interface as detailed above. Then you create iOS and Android implementations of that. The iOS one could look something like this in swift:
public final class IosTokenProvider: TokenProvider {
public func getToken(callback: @escaping (String) -> Void) {
// Do your async work here then invoke
// the callback when you have the value you need
}
}
Then in your KMP code where you need to use this, you do so like here:
internal class SharedApi(
private val client: ApiClient,
private val tokenProvider: TokenProvider,
) {
suspend fun fetchData() {
val token = fetchToken()
return client.getData(token)
}
private suspend fun fetchToken(): String {
return suspendCancellableCoroutine { continuation ->
tokenProvider.getToken(
callback = { token -> continuation.resume(token) }
)
}
}
}
The intention here is that we are not exposing the complexity of coroutines to underlying platforms, but just providing an API in which a particular platform can provide a token when the KMP code needs it. In my humble opinion this is a more idiomatic implementation and more enjoyable for iOS devs as they are not having to deal with the headache of integrating coroutines into their iOS codebase