扩展为可选发布者的默认空值?

时间:2020-06-14 13:03:53

标签: swift combine

我正试图将可选发布者传递到我视图的.onReceive中。我不想像这样强制包装它:

let refreshPublisher: AnyPublisher<Void, Never>?

var body: some View {
    Group {
        ...
    }
    .onReceive(refreshPublisher!) {...}
}

所以我要传递一个空的默认值,像这样:

var body: some View {
    Group {
        ...
    }
    .onReceive(refreshPublisher ?? Empty<Void, Never>().eraseToAnyPublisher()) {...}
}

这真的很冗长,想在Optional发布者上添加扩展名,如下所示:

extension Optional where Wrapped == Publisher { // Incorrect syntax, doesn't compile
    func orEmpty() -> AnyPublisher<Void, Never> { ... }
}

这样,我可以结束或执行以下操作:

var body: some View {
    Group {
        ...
    }
    .onReceive(refreshPublisher.orEmpty()) {...}
}

这样有可能还是更好的方式来处理非可选链中的可选发布者?

1 个答案:

答案 0 :(得分:3)

对于您的特定问题,肯定有可能。我只是不会这样做。

请注意,在Combine.之前添加了Publisher。有一种叫做Optional.Publisher的类型会遮盖Combine.Publisher,这就是导致您出错的原因。

extension Optional where Wrapped: Combine.Publisher {
    func orEmpty() -> AnyPublisher<Wrapped.Output, Wrapped.Failure> {
        self?.eraseToAnyPublisher() ?? Empty().eraseToAnyPublisher()
    }
}

代替这种方式,我将默认值设置为Empty,并且完全不使用Optional:

let refreshPublisher: AnyPublisher<Void, Never>

init(refreshPublisher: AnyPublisher<Void, Never> = Empty().eraseToAnyPublisher()) {
    self.refreshPublisher = refreshPublisher
}

我还将对此进行重新设计,以使呼叫者可以传递他们想要的任何发布者,而不是强加AnyPublisher

let refreshPublisher: AnyPublisher<Void, Never>

init<Refresh>(refreshPublisher: Refresh) where Refresh: Publisher,
    Refresh.Output == Void, Refresh.Failure == Never {
        self.refreshPublisher = refreshPublisher.eraseToAnyPublisher()
}

init() {
    self.init(refreshPublisher: Empty())
}