DEV Community

RockAndNull
RockAndNull

Posted on • Originally published at rockandnull.com on

Converting Callback-based SDK methods to Coroutines in Kotlin

Converting Callback-based SDK methods to Coroutines in Kotlin

Kotlin's coroutines are an excellent feature of the language that makes asynchronous programming enjoyable and easy to understand.

However, even if you have organized your project neatly and extensively use coroutines, you may encounter a third-party library at some point that still uses old-fashioned callbacks. Combining callbacks and coroutines can be unpleasant, to say the least.

Luckily, there is a solution to this problem. You can wrap these callbacks and "transform" them into coroutines. It's generally a good practice to wrap your external dependencies and provide a consistent coroutine-style interface, regardless of the interface offered by the third-party libraries.

Below is a short code example that demonstrates how to quickly convert a library that uses callbacks into a coroutine interface, so you can start using it promptly.

    suspend fun callCallbackBasedSdkSomeMethod(): String {

        return suspendCancellableCoroutine { continuation -> // 1.

            CallbackBasedSdk.getInstance().someMethod( // 2.
                object : Callback {
                    override fun onSuccess(result: String) {
                        continuation.resume(result) // 3.
                    }

                    override fun onFailure(e: TerminalException) {
                        continuation.resumeWithException(e) // 4.
                    }
                },
            )

            continuation.invokeOnCancellation { // 5.
                CallbackBasedSdk.getInstance().stopSomeMethod()
            }
        }
    }
Enter fullscreen mode Exit fullscreen mode
  1. Use Kotlin's suspendCancellableCoroutine to convert calls from a callback-based SDK to a coroutine-based one.
  2. Inside the suspendCancellableCoroutine'sblock parameter call the callback-based SDK method as you would normally do.
  3. Use the continuation.resumt() to resume the execution of the coroutine and provide results.
  4. Optionally, use continuation.resumeWithException() to throw an exception in the context of the coroutine.
  5. In case the coroutine is canceled, you can define if any action needs to be taken to cancel the request in flight.

Hopefully, this help you maintain a consistent coroutine-based codebase in your Kotlin project.

Happy coding!

Top comments (1)

Collapse
 
zurcher profile image
Alejandro Zurcher • Edited

Thanks for sharing! This is very handy indeed, I recently did the same to consume the Firebase Storage API as It fully relies on a Callback approach.