Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
485 views
in Technique[技术] by (71.8m points)

swift - How to use CombineLates when when publishers failure types is not equivalent?

I have two functions which return AnyPublisher with different failure type: Never and Error. When using these functions in the CombineLates, then compilation fails with an error: Generic struct 'CombineLatest' requires the types 'Error' and 'Never' be equivalent

Function which never fails:

func foo() -> AnyPublisher<Int, Never> {
    Result<Int, Never>
        .success(1).publisher
        .eraseToAnyPublisher()
}

Function which sometimes fails:

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

foo & boo functions usage:

Publishers.CombineLatest(foo(), boo())

Error generated:

Generic struct 'CombineLatest' requires the types 'Error' and 'Never' be equivalent

How to use CombineLates when publisher's failure types are not equivalent?


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Whenever you need to match failure types in Combine, for a Never failure type, like a Just publisher, you'd use setFailureType(to:):

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

let p1 = p.setFailureType(to: Error.self)
          .eraseToAnyPublisher()  // AnyPublisher<Int, Error>

For a non-Never failure, you'd need to use .mapError:

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

So, in your case, if you want to change foo's return value, you'd do:

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

And if you don't want to change foo, but still use with with bar, you can do:

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...