https://kotlinlang.org logo
n

Nicolas Verinaud

09/22/2021, 10:59 AM
[RESOLVED ] Hi ! I am writing a shared interface with a suspend function. In iOS it generates a protocol with a method with a completionHandler which is great. Problem is how can I handle cancellation ? My shared interface :
Copy code
interface CanRetrieveAuthorizationToken {
    suspend fun getToken(): String
}
The corresponding protocol :
Copy code
public protocol CanRetrieveAuthorizationToken {
   
    /**
     @note This method converts instances of CancellationException to errors.
     Other uncaught Kotlin exceptions are fatal.
    */
    func getToken(completionHandler: @escaping (String?, Error?) -> Void)
}
1
m

mbonnin

09/22/2021, 11:05 AM
n

Nicolas Verinaud

09/22/2021, 1:29 PM
Interesting, thanks @mbonnin. Problem is, my interface is not used by native code (implemented by though), so the native code does not need the cancellation mechanism, it assumes the implementation can manage the cancellation correctly.
Maybe I should pass the cancellation mechanism to the
getToken
method ? Or add a
cancelGetToken
method to the interface ?
m

mbonnin

09/22/2021, 1:35 PM
Not an expert by any means but the above library integrates with
RxSwift
and/or
Combine
so I guess it has a way to handle cancellation from them and if you don't want to use these frameworks, it should be doable too. Maybe not easy though
n

Nicolas Verinaud

09/22/2021, 2:11 PM
No because the
suspend
function is not used by swift but implemented by swift. The swift code needs a way to know when to cancel its job.
👍 1
m

mbonnin

09/22/2021, 2:14 PM
Ah got it!
Maybe expose something that uses a
CancellableContinuation
instead?
n

Nicolas Verinaud

09/22/2021, 2:25 PM
Great, I check this 😉
Okay, I ended up with the following solution : I did transform the
getToken
method like this :
Copy code
fun getToken(onSuccess: (String) -> Unit, onError: (Throwable) -> Unit): Disposable
This allows swift code to be cancellable by returning an instance of
Disposable
which is a class I created inspired by C# (wrapping a method executed when the disposable is disposed aka cancelled). I then wrapped the call to the new
getToken
method in a suspend function using
suspendCancellableCoroutine
to make it usable alongside other suspending function (in my case http calls using ktor). More info here : https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/suspend-cancellable-coroutine.html. Thanks @mbonnin for the hint about
CancellableContinuation
🙌
👍 1
Merci cher confrère 😉
👍 1