Asynchronous callbacks can be converted into synchronous suspend functions using either suspendCoroutine() or suspendCancellableCoroutine(). Typically you would create a suspend extension function version of the corresponding asynchronous call so you can use it anywhere you would normally use the SDK call (rather than using suspendCoroutine at each location, since it is somewhat clumsy).
suspendCancellableCoroutine is used when the API call provides a way to cancel it early. If that's the case, you can make your suspend function support coroutine cancellation, so the API call is automatically cancelled if the associated coroutine is cancelled. Exactly what you want since on Android, lifecycleScope and viewModelScope automatically cancel their coroutines when their associated lifecycles are over.
I don't know what version of AWS SDK you're using, but here's approximately how you what your suspend function would look like:
suspend fun AWSMobileClient.signIn(userName: String, password: String, someParam: Any?): SignInResult = suspendCoroutine { continuation ->
signIn(userName, password, someParam, object : Callback<SignInResult> {
override fun onResult(signInResult: SignInResult) {
continuation.resume(signInResult)
}
override fun onError(e: Exception) {
continuation.resumeWithException(e)
}
})
}
I don't know the type of that third parameter so I just put Any?.
And now your existing function would become:
override suspend fun login(username: String, password: String): ResultResponse<SignInResult> {
return try {
val signInResult = AWSMobileClient.getInstance().signIn(username, password, null)
ResultResponse.Success(signInResult)
} catch(e: Exception) {
ResultResponse.Error(e)
}
}
I'm not sure if ResultResponse is your own class. In case it is, be aware the Kotlin standard library already contains a Result class, which would make this function simpler with the use of runCatching:
override suspend fun login(username: String, password: String): Result<SignInResult> {
return runCatching {
AWSMobileClient.getInstance().signIn(username, password, null)
}
}