n

    Nicolas Verinaud

    1 year ago
    [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 :
    interface CanRetrieveAuthorizationToken {
        suspend fun getToken(): String
    }
    The corresponding protocol :
    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)
    }
    mbonnin

    mbonnin

    1 year ago
    n

    Nicolas Verinaud

    1 year ago
    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 ?
    mbonnin

    mbonnin

    1 year ago
    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

    1 year ago
    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.
    mbonnin

    mbonnin

    1 year ago
    Ah got it!
    Maybe expose something that uses a
    CancellableContinuation
    instead?
    n

    Nicolas Verinaud

    1 year ago
    Great, I check this 😉
    Okay, I ended up with the following solution : I did transform the
    getToken
    method like this :
    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
    🙌
    Merci cher confrère 😉