结合框架的Publisher mapError

时间:2020-03-02 16:38:57

标签: swift combine

我有这样的设置,但错误如下所示

enum DataError: Error {
    case failed(error: Error)
}

enum UIError: Error {
    case failed(error: Error)
}

struct SomeData {

}

func foo() -> AnyPublisher<Result<[SomeData]?, DataError>, Never> {
    ...
}

func foo2() -> AnyPublisher<Result<[SomeData]?, UIError>, Never> {
    return foo()
            .mapError { error -> UIError 
                switch error {
                    ....
                }

                return UIError.failed(error: $0)
            }
            .eraseToAnyPublisher() ===> // Error Cannot convert return expression of type 'AnyPublisher<Result<[SomeData]?, DataError>, UIError>' to return type 'AnyPublisher<Result<[T], UIError>, Never>'
}

错误消息看起来很简单,但无法完全解决。

2 个答案:

答案 0 :(得分:1)

您可能需要这样的东西:

发布者不返回错误。结果有错误,因此您需要mapError结果。

我修改了Error枚举以使其更易于理解。

    enum DataError: Error {
        case failed
    }

    enum UIError: Error {
        case failed
    }

    func foo2() -> AnyPublisher<Result<[SomeData]?, UIError>, Never> {
        return foo().map { result in
            result.mapError { _ -> UIError in
                UIError.failed
            }
        }.eraseToAnyPublisher()
    }

答案 1 :(得分:0)

Result中使用Combine是没有意义的,因为您的Publisher总是会发出值或失败。它们永远不应该发出包含错误的值。

一旦您摆脱了Result的使用,这些错误就会消失。

func foo() -> AnyPublisher<[SomeData], DataError> {
    ...
}

func foo2() -> AnyPublisher<[SomeData], UIError> {
    return foo()
        .mapError { error -> UIError in
            switch error {
            ...
            }

            return UIError.failed(error: error)
        }
        .eraseToAnyPublisher()
}

无论是使用Result还是使用Publisher,您通常都不需要使用Optional,因为如果发生错误,根本就不会有值,与完成处理程序不同,无需返回nil值。