Skip to content

Instantly share code, notes, and snippets.

@danailalexiev
Created October 5, 2022 07:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save danailalexiev/1af7e37c49169a32291ebf30e354e0b7 to your computer and use it in GitHub Desktop.
Save danailalexiev/1af7e37c49169a32291ebf30e354e0b7 to your computer and use it in GitHub Desktop.
Kotlin Interop Swift
import Foundation
import sdk
typealias NativeCompletionHandler<Result> = (Result?, Error?) -> ()
typealias NativeCall<Result> = (@escaping NativeCompletionHandler<Result>) -> NativeCancellable
func convertToAsync<Result>(kotlinCall call: @escaping NativeCall<Result>) async throws -> Result {
let cancellableActor: NativeCancellableActor = NativeCancellableActor()
return try await withTaskCancellationHandler(
operation: {
try await withUnsafeThrowingContinuation { continuation in
let completionHandler: NativeCompletionHandler<Result> = { result, error in
if (result != nil) {
continuation.resume(with: .success(result!))
} else {
continuation.resume(with: .failure(error!))
}
}
let cancellable = call(completionHandler)
Task { await cancellableActor.setCancellable(cancellable: cancellable) }
}
},
onCancel: {
Task { await cancellableActor.cancel() }
}
)
}
private actor NativeCancellableActor {
private var isCancelled: Bool = false
private var cancellable: NativeCancellable?
func setCancellable(cancellable: NativeCancellable) {
if (isCancelled) {
cancellable.cancel()
}
self.cancellable = cancellable
}
func cancel() {
cancellable?.cancel()
isCancelled = true
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment