# Kotlin Coroutines and Swift, revisited

DevFeed: [Kotlin Coroutines and Swift, revisited](<https://devfeed.tech/articles/kotlin-coroutines-and-swift-revisited-25003.md>)

Original publisher: [Read original article](<https://dev.to/touchlab/kotlin-coroutines-and-swift-revisited-j5h>)

Author: Russell Wolf

Published: 2021-06-04T20:50:38Z

Content type: tutorial

Language: en

Sources: [DEV Community 👩💻👨💻: Russell Wolf](<https://devfeed.tech/sources/dev-community-russell-wolf.md>)

Topics: [Kotlin](<https://devfeed.tech/topics/kotlin.md>), [kotlin-coroutines](<https://devfeed.tech/topics/kotlin-coroutines.md>), [Coroutines](<https://devfeed.tech/topics/coroutines.md>), [Swift](<https://devfeed.tech/topics/swift.md>), [iOS](<https://devfeed.tech/topics/ios.md>), [reactive](<https://devfeed.tech/topics/reactive.md>), [implementation](<https://devfeed.tech/topics/implementation.md>)

Tags: [article](<https://devfeed.tech/tags/article.md>), [code](<https://devfeed.tech/tags/code.md>), [coding](<https://devfeed.tech/tags/coding.md>), [community](<https://devfeed.tech/tags/community.md>), [coroutines](<https://devfeed.tech/tags/coroutines.md>), [development](<https://devfeed.tech/tags/development.md>), [engineering](<https://devfeed.tech/tags/engineering.md>), [implementation](<https://devfeed.tech/tags/implementation.md>), [inclusive](<https://devfeed.tech/tags/inclusive.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [kotlin-coroutines](<https://devfeed.tech/tags/kotlin-coroutines.md>), [kotlinmultiplatform](<https://devfeed.tech/tags/kotlinmultiplatform.md>), [reactive](<https://devfeed.tech/tags/reactive.md>), [software](<https://devfeed.tech/tags/software.md>), [swift](<https://devfeed.tech/tags/swift.md>)

## AI overview

This article revisits interoperability patterns between Kotlin coroutines and Swift on iOS. It updates a callback wrapper by moving CoroutineScope management into a Kotlin constructor, adds a Swift wrapper to hide Kotlin implementation details, and discusses adapting callback-based streams for reactive frameworks including Combine.

## Source excerpt

Last year I wrote about a pattern for interop between Kotlin coroutines and RxSwift. I appreciate the attention it received, particularly where people have applied it to other reactive frameworks, and even including a code-generation plugin using the same ideas. I figure it's about time I talk about my own updated thinking on these patterns. If you haven't read the previous article, I suggest going through that first for context. Kotlin updates We'll stick to the same repository class as the original article, and walk through exposing it to iOS. class ThingRepository { suspend fun getThing(succeed: Boolean): Thing { delay(100) if (succeed) { return Thing(0) } else { error("oh no!") } } fun getThingStream( count: Int, succeed: Boolean ): Flow<Thing> = flow { repeat(count) { delay(100) emit(Thing(it)) } if (!succeed) error("oops!") } } In the previous article, I suggested the following pattern for wrapping suspend functions with callbacks that could run on iOS class SuspendWrapper<T>(private val suspender: suspend () -> T) { init { freeze() } fun subscribe( scope: CoroutineScope, onSuccess: (item: T) -> Unit, onThrow: (error: Throwable) -> Unit ): Job = scope.launch { try { onSuccess(suspender().freeze()) } catch (error: Throwable) { onThrow(error.freeze()) } }.freeze() } After having played with these patterns more, a drawback to this emerged. This class expects a CoroutineScope to be supplied by the caller (which will be in Swift) at subscription time. This can be nice for flexibility if it might be called in different contexts, but in the vast majority of cases in practice this will live in some sort of class with its own scope, and it's much more pleasant to work with the scope from Kotlin than from Swift. So let's make the scope a constructor parameter instead. class SuspendWrapper<T : Any>( private val scope: CoroutineScope, private val suspender: suspend () -> T ) { init { freeze() } fun subscribe( onSuccess: (item: T) -> Unit, onThrow: (error: Throwable) -> Un