Skip to content

Instantly share code, notes, and snippets.

@har5hit
Created August 3, 2022 20:25
Show Gist options
  • Save har5hit/6b0b34a91c38af3485e42e6cca2f5ebf to your computer and use it in GitHub Desktop.
Save har5hit/6b0b34a91c38af3485e42e6cca2f5ebf to your computer and use it in GitHub Desktop.
Calling kotlin suspend functions from Swift

Works

Suspend function can be called from swift on Main thread. Examples:

// Sample.kt
suspend fun add(a: Int, b: Int): Int {
    return a + b;
}

// Sample.swift
// Option - 1
SampleKt.add(a: 1, b: 2) { total, error in
    debugPrint("completionHandler: total \(total) error: \(error)")
}

// Option - 2
Task.init {
    do {
        let total = try await SampleKt.add(a: 1, b: 2)
            debugPrint("await: total \(total)")
        } catch {
            print("error \(error)")
        }
    }

Doesn't Work

Running suspend functions on background thread from swift doesn't work. Examples:

  • Backgroud thread using DispatchQueue
typealias Dispatch = DispatchQueue

extension Dispatch {
    static func background(_ task: @escaping () -> Void) {
        Dispatch.global(qos: .background).async {
            task()
        }
    }
    static func main(_ task: @escaping () -> Void) {
        Dispatch.main.async {
            task()
        }
    }
}

Dispatch.background {
    SampleKt.add(a: 1, b: 2) { total, error in
        debugPrint("Dispatch: total \(total) error: \(error)")
    }
}
Exception NSException * "Calling Kotlin suspend functions from Swift/Objective-C is currently supported only on main thread"
  • Running suspend function block from swift using coroutine from kotlin file.
// Sample.kt
fun <T> runWithCoroutine(dispatcher: CoroutineDispatcher, block: () -> T): Closeable {
    val job = Job()
    CoroutineScope(dispatcher + job).launch {
        block()
    }
    return object : Closeable {
        override fun close() {
            job.cancel()
        }
    }
}

// Sample.swift
SampleKt.runWithCoroutine(dispatcher: AppModule.dispatchers.io) {
    SampleKt.add(a: 1, b: 2) { total, error in
        debugPrint("runWithCoroutine: total \(total) error: \(error)")
    }
}
Exception NSException * "Calling Kotlin suspend functions from Swift/Objective-C is currently supported only on main thread"
@har5hit
Copy link
Author

har5hit commented Jan 4, 2023

Thanks @hiasel, will check it out!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment