How do you convert a library function with two completion handlers into an async function?

362 Views Asked by At

I need to wrap a function as below from a library into an async function. The error on my First Trial as below is:

Missing argument for parameter 'errorHandler' in call.

How can I wrap it properly? Your comments will be appreciated.

Original Function:

func createConverter(id: String, successHandler: @escaping (Converter) -> Void, errorHandler: @escaping (Error) -> Void) -> Cancellable
func createConverter(id: String) async throws -> Converter {
    return await withCheckedThrowingContinuation({
        (continuation: CheckedContinuation<Converter, Error>) in
        createConverter(id: id) { result in
            switch result {
            case .success(let converter):
                continuation.resume(returning: converter)
            case .failure(let error):
                continuation.resume(throwing: error)
            }
        }
    })
}
1

There are 1 best solutions below

5
HangarRash On BEST ANSWER

Since the original createConverter has three parameters, you need to provide all three. You are missing the 3rd. Your attempt assumes there is only one closure parameter (of type Result<Converter, Error>) instead of the two separate closure parameters.

You should also add try before the await.

func createConverter(id: String) async throws -> Converter {
    return try await withCheckedThrowingContinuation { (continuation: CheckedContinuation<Converter, Error>) in
        let cancellable = createConverter(id: id) { (converter: Converter) in
            continuation.resume(returning: converter)
        } errorHandler: { error in
            continuation.resume(throwing: error)
        }
    }
}

This compiles but I have no way to verify the result. This also makes no use of the original Cancellable return value of the original createConverter.

Since I don't have whatever library you have, this was verified in a Playground using the following:

import Combine

// Dummy
struct Converter {
}

// Original function
func createConverter(id: String, successHandler: @escaping (Converter) -> Void, errorHandler: @escaping (Error) -> Void) -> Cancellable {
    return AnyCancellable { // Just enough so it compiles
    }
}

// New function
func createConverter(id: String) async throws -> Converter {
    return try await withCheckedThrowingContinuation { (continuation: CheckedContinuation<Converter, Error>) in
        let cancellable = createConverter(id: id) { (converter: Converter) in
            continuation.resume(returning: converter)
        } errorHandler: { error in
            continuation.resume(throwing: error)
        }
    }
}