将 nil 替换为空或组合中的错误

Soh*_*ard 1 reactive-programming swift combine

我有一个这样的组合发布者:

enum RemoteError: Error {
    case networkError(Error)
    case parseError(Error)
    case emptyResponse
}

func getPublisher(url: URL) -> AnyPublisher<Entiy, RemoteError> {
    return URLSession.shared
        .dataTaskPublisher(for: url)
        .map(\.data)
        .decode(type: RemoteResponse.self, decoder: decoder)
        .mapError { error -> RemoteError in
            switch error {
            case is URLError:
                return .networkError(error)
            default:
                return .parseError(error)
            }
        }
        .map { response -> Entiy in
            response.enitities.last
        }
        .eraseToAnyPublisher()
}

struct RemoteResponse: Codable {
    let enitities: [Entity]
    let numberOfEntries: Int
}

struct Entity {

}
Run Code Online (Sandbox Code Playgroud)

通过上述设置,编译器会抱怨,因为response.enitities.last可能为零。问题是我可以用空发布者替换 nil 吗?如果不能,我可以用emptyResponse合并链中的错误替换它吗?第一个选项是更可取的。

LuL*_*aGa 6

您在这里有几个选择。

如果您不希望发布者在实体为空的情况下发布任何内容,您可以使用coampactMap而不是映射:

.compactMap { response in
   response.entities.last
}
Run Code Online (Sandbox Code Playgroud)

如果您想在这种情况下发布错误,您可以使用tryMap它允许您抛出Error. 你需要mapError追随它:

.tryMap { response in
    guard let entity = response.entities.last else {
        throw RemoteError.emptyResponse
    }
    return entity
}
.mapError { error -> RemoteError in
    switch error {
    case is URLError:
        return .networkError(error)
    case is DecodingError:
        return .parseError(error)
    default:
        return .emptyResponse
    }
}
Run Code Online (Sandbox Code Playgroud)