Async
Swift async methods are exported as functions that return CompletableFuture<T> on the JVM side. This lets you use them with Kotlin coroutines via kotlinx-coroutines-jdk8.
Exporting an async method
Section titled “Exporting an async method”import Swift4jimport Dispatch
@jvmstruct DataFetcher { func fetchData() async -> String { try? await Task.sleep(nanoseconds: 1_000_000_000) return "Data from Swift" }
func process() async throws { for i in 0..<5 { print("Step \(i)") try await Task.sleep(nanoseconds: 500_000_000) } }}Calling from Kotlin with coroutines
Section titled “Calling from Kotlin with coroutines”Add kotlinx-coroutines-jdk8 to your Kotlin project, then use .await() to suspend until the future completes:
import kotlinx.coroutines.future.awaitimport kotlinx.coroutines.runBlocking
fun main() = runBlocking { System.loadLibrary("MyLibrary")
val fetcher = DataFetcher()
val data = fetcher.fetchData().await() println(data) // Data from Swift
fetcher.process().await()}Calling from Java
Section titled “Calling from Java”Without coroutines, use the CompletableFuture API directly:
DataFetcher fetcher = new DataFetcher();
fetcher.fetchData() .thenAccept(data -> System.out.println(data)) .join();Error handling
Section titled “Error handling”async throws Swift methods propagate exceptions through the CompletableFuture. Catch them with CompletableFuture.exceptionally() or handle them at the coroutine call site:
try { fetcher.process().await()} catch (e: Exception) { println("Failed: ${e.message}")}Threading
Section titled “Threading”Swift async tasks run on Swift’s cooperative thread pool. The CompletableFuture is completed on whatever thread Swift’s runtime chooses. On Android, do not update UI directly inside the future callback — post the result to the main thread using Handler or a StateFlow.