swiftasync-awaitconcurrencywrappercompletionhandler

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


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)
            }
        }
    })
}

Solution

  • 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)
            }
        }
    }