I'm using the swift Result<>
generic in a function completion block, but passing it to another completion block with a protocol type doesn't work as expected.
public protocol Journey { }
class CommsJourney: Journey { }
typealias Completion = (Result<[Journey]?, Error>) -> Void
typealias CommsCompletion = (Result<[CommsJourney]?, Error>) -> Void
class Comms {
func refreshTimes(completion: @escaping CommsCompletion) {
let array = [CommsJourney()]
completion(.success(array))
}
}
/**
Completion block returns `Journey` protocol if successful
*/
func refreshTimes(completion: @escaping Completion) {
// Passing the previous completion block fails to compile as signatures are different
// Comms().refreshTimes(completion: completion)
Comms().refreshTimes { (result) in
switch result {
case .success(let results):
// result is `CommsCompletion` yet returns perfectly fine
completion(.success(results))
case .failure(let error):
completion(.failure(error))
}
}
}
Cannot convert value of type 'Completion' (aka '(Result<Optional<Array>, Error>) -> ()') to expected argument type 'CommsCompletion' (aka '(Result<Optional<Array>, Error>) -> ()')
I'd like to understand why passing the completion doesn't work, yet sending the result does. And also what is the best way to correct this? Is my switch
example the easiest/best solution?
EDIT ----
I've been pointed to this q/a Swift generic coercion misunderstanding which either goes completely over my head, or isn't specific to my case. As I can fix this by simply extracting the result
and then forwarding it on it seems overkill to create an intermediate Any...
object.
EDIT ----- Playground gist here https://gist.github.com/ddaddy/d58b648dbe82a1c63fe23541cc1aad40