how can i wrap this (AdsWizz) Kotlin callback function in a couroutine?

ajonno :

I'm new to coroutines and having a hard time figuring out how to correctly wrap an existing callback in a coroutine.

My goal is to be able to do the following:

lifecycleScope.launch {
    withContext(Dispatchers.Main) {
        val theResult = getPreRollAd()      //1. call this suspending func and wait for result

        doSomethingWithResult(theResult)    //2. now that the result is returned from AdsWizz API (below), do something with it 
    }
}

Here is the AdsWizz API call that I'd like to "wrap":

val adReqInterface: AdRequestHandlerInterface =  object :
    AdRequestHandlerInterface {

    override fun onResponseError(error: AdswizzSDKError) {
        Timber.e("onResponseError $error")
    }

    override fun onResponseReady(adResponse: AdResponse) {
        Timber.d( "onResponseReadySingleAd")

        //this contains the url to the ad, title, etc..
        !!!*** I WANT TO RETURN THE adResponse.mediaFile?.source string back to "theResult" variable above (in lifecycleScope.launch {.... )


    }
}

try {
    AdswizzSDK.getAdsLoader().requestAd(adReqParams, adReqInterface)

} catch (e: IllegalArgumentException) {
    Timber.d( "IllegalArgumentException")
} catch (e: SecurityException) {
    Timber.d( "SecurityException")
} catch (e: Exception) {
    Timber.d( "other exception")
    e.printStackTrace()
}

I've tried using suspendCoroutine {... to wrap but nothing is working. Really appreciate someones help re the right way to achieve this.

Pierluigi :

the right way to do it is to use suspendCancellableCoroutine. It can return a result or can be cancelled with an exception.

suspend fun getPreRollAd(): AdResponse {
return suspendCancellableCoroutine {

    ...

    val adReqInterface: AdRequestHandlerInterface =  object : AdRequestHandlerInterface {

        override fun onResponseError(error: AdswizzSDKError) {
            Timber.e("onResponseError $error")
            it.cancel(error)
        }

        override fun onResponseReady(adResponse: AdResponse) {
            Timber.d( "onResponseReadySingleAd")
            it.resume(adResponse)
        }

    }

    AdswizzSDK.getAdsLoader().requestAd(adReqParams, adReqInterface)
}

}


viewModelScope.launch {
  val result = try {
    getPreRollAd()
  } catch(e: Throwable) {
    null
  }

  ...
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=174449&siteId=1