Combine (preview)
SKIE has a preview support for bridging Kotlin Coroutines with Apple's Combine framework.
This allows you to use Kotlin Coroutines in Swift code that uses Combine.
The bridging supports converting suspend
functions into Combine.Future
types,
and Flows into Combine.Publisher
types.
Since Combine is usually being replaced with Swift Concurrency, we added this feature on top of the SKIE's native support for bridging Kotlin Coroutines with Swift Concurrency.
Each of these features can be enabled separately using the SKIE Gradle configuration.
suspend fun
→ Combine.Future
To enable the support for Combine.Future
, add the following to your build.gradle.kts
:
skie {
features {
enableFutureCombineExtensionPreview = true
}
}
When enabled,
SKIE will extend Combine.Future
with an initializer accepting any async
lambda.
With it, you can easily convert any suspend
function into Combine.Future
.
Let's take a look at an example usage. We'll declare a suspending global function helloWorld
.
suspend fun helloWorld(): String {
return "Hello World!"
}
Then in Swift you can use the new Future
initializer like so:
let future = Future(async: helloWorld)
future.sink { error in
// Handle an error throw by the function.
// Note that this could also be `CancellationError`.
} receiveValue: { value in
// Value is a `String` "Hello World!"
print(value)
}
It's important to understand how Combine and its operators work.
The example above doesn't store the cancellable returned by sink
,
so it would immediately cancel and receiveValue
wouldn't get called.
Additionally, Futures are hot and will invoke the provided async
immediately.
This means Futures don't wait for calling .sink
on them.
Futures also don't support cancellation.
Flow
→ Combine.Publisher
To enable the support for Combine.Publisher
, add the following to your build.gradle.kts
:
skie {
features {
enableFlowCombineConvertorPreview = true
}
}
When enabled,
each Flow bridged to Swift by SKIE will contain a toPublisher()
method.
Use this if you need to interface with Combine code and can't use Swift's native AsyncSequence
.
Let's take a look at an example usage. We'll declare a global function helloWorld
returning a Flow
.
fun helloWorld(): Flow<String> {
return flow {
emit("Hello")
delay(1.seconds)
emit("World")
delay(1.seconds)
emit("!")
}
}
Then in Swift you can use the toPublisher()
function.
let publisher = helloWorld().toPublisher()
publisher.sink { value in
// Value is a `String` type
// Receives with a 1-second delay between them:
// - "Hello"
// - "World"
// - "!"
}
It's important to understand how Combine and its operators work.
The example above doesn't store the cancellable returned by sink
,
so it would immediately cancel and receiveValue
wouldn't get called.