当发布者失败类型不相等时如何使用CombineLates?

Ram*_*mis 3 swift combine

我有两个函数返回具有不同失败类型的AnyPublisher : NeverError。在JointLates中使用这些函数时,编译失败并出现错误:Generic struct 'CombineLatest' require the types 'Error' and 'Never' be equal

永不失败的功能:

func foo() -> AnyPublisher<Int, Never> {
    Result<Int, Never>
        .success(1).publisher
        .eraseToAnyPublisher()
}
Run Code Online (Sandbox Code Playgroud)

有时会失败的功能:

func boo() -> AnyPublisher<Int, Error> {
    Result<Int, Error>
        .failure(NSError(domain: "d", code: -1))
        .publisher.eraseToAnyPublisher()
}
Run Code Online (Sandbox Code Playgroud)

foo 和 boo 函数用法:

Publishers.CombineLatest(foo(), boo())
Run Code Online (Sandbox Code Playgroud)

生成错误:

Generic struct 'CombineLatest' requires the types 'Error' and 'Never' be equivalent
Run Code Online (Sandbox Code Playgroud)

当发布者的失败类型不相等时如何使用CombineLates?

New*_*Dev 5

每当您需要在合并中匹配失败类型时,对于Never失败类型(例如Just发布者),您可以使用setFailureType(to:)

let p: AnyPublisher<Int, Never> = ...

let p1 = p.setFailureType(to: Error.self)
          .eraseToAnyPublisher()  // AnyPublisher<Int, Error>
Run Code Online (Sandbox Code Playgroud)

对于非Never失败,您需要使用.mapError

let p2 = p1.mapError { CustomError(wrapping: $0) }
           .eraseToAnyPublisher() // AnyPublisher<Int, CustomError> 
Run Code Online (Sandbox Code Playgroud)

因此,在您的情况下,如果您想更改 的foo返回值,您可以这样做:

func foo() -> AnyPublisher<Int, Error> {
    Result<Int, Never>
        .success(1).publisher
        .setFailureType(to: Error.self)
        .eraseToAnyPublisher()
}
Run Code Online (Sandbox Code Playgroud)

如果你不想改变foo,但仍然使用 with bar,你可以这样做:

Publishers.CombineLatest(foo().setFailureType(to: Error.self), boo())
   .map { (f, b) in
     // f and b are Ints, as emitted by foo and bar, respectively
   }
Run Code Online (Sandbox Code Playgroud)