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

Time:11-12

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

CodePudding user response:

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