Converting method with call backs to coroutine

#1

Hi everyone, I have recently started to learn Kotlin and need help with converting a function with callbacks to coroutine.

I have converted my function as below.

private suspend inline fun tryGettingTokenSilently(account: IAccount?, authenticationManager: AuthenticationManager): OneDriveAuth = suspendCoroutine { continuation ->
    authenticationManager.callAcquireTokenSilent(account, true, object : MSALAuthenticationCallback {
        override fun onSuccess(authenticationResult: AuthenticationResult) {
            continuation.resume(OneDriveAuth.Success(authenticationResult.account.username, authenticationResult.accessToken))
        }

        override fun onError(exception: MsalException) {
            when (exception) {
                is MsalClientException ->
                    continuation.resume(OneDriveAuth.Fail(exception))
                is MsalServiceException ->
                    continuation.resume(OneDriveAuth.Fail(exception))
                is MsalUiRequiredException -> {
                    continuation.resume(OneDriveAuth.RequireLogin)
                }
            }
        }

        override fun onError(exception: Exception) {
            continuation.resume(OneDriveAuth.Fail(exception))
        }

        override fun onCancel() {
            continuation.resume(OneDriveAuth.UserCancelled)
        }
    })
}

I am having hard time calling it from my utility class. For example, I’ve tried with

runBlocking {
            if (Logger.INSTANCE.DEBUG) {
                Logger.INSTANCE.log(LOG_TAG, "getTokenOrRequestLogin runBlocking")
            }
            tryGettingTokenSilently(account, authenticationManager)
        }

Which blocks infinitely, it looks like continuation.resume(s) never called and it just hangs there.

I know I can do the following in my activity/fragment

 CoroutineScope(Dispatchers.Main).launch{
        val result = tryGettingTokenSilently(....)
  }

But, this returns Job and prevents me getting the return from the method. I want to return the value to another method.What am I doing wrong?

#2

Yes, I agree.
Try to debug or putting some logging on each callback.
Try to replace:

        override fun onError(exception: MsalException) {
            when (exception) {
                is MsalUiRequiredException ->
                    continuation.resume(OneDriveAuth.RequireLogin)
                else ->
                    continuation.resume(OneDriveAuth.Fail(exception))
            }
        }