2

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)
            }
        }
    })
}
TylerP
  • 9,600
  • 4
  • 39
  • 43
crecre
  • 23
  • 3
  • 1
    `createConverter` Takes 2 separate closures, but you’re only calling it with 1. See https://developer.apple.com/videos/play/wwdc2021/10194/ for a really good walkthrough – Alexander Nov 12 '22 at 00:01
  • just throw the error instead or return a Result – lorem ipsum Nov 12 '22 at 01:13

1 Answers1

1

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)
        }
    }
}
HangarRash
  • 7,314
  • 5
  • 5
  • 32
  • Thank you so much HagarRash. Your correction compiles with a little modification of – crecre Nov 12 '22 at 01:50
  • Looks like you hit return to soon. What needs to be changed? The code I posted compiled fine for me. – HangarRash Nov 12 '22 at 01:56
  • (throwing error as! Error) for the error type conforming a protocol in the library. Actually I was not accustomed with putting second closure parameter. – crecre Nov 12 '22 at 01:59
  • Let Xcode do code completion for you. It makes it so much simpler than trying to get the syntax correct by hand. – HangarRash Nov 12 '22 at 02:01
  • By highlighting the function name(Class.function) and right-clicking, I could not see the 'Wrap to async' option activated. – crecre Nov 12 '22 at 02:11