Swift 合并尚未发送值的发布者



我有一个需要在日期变化时重新评估的发布者,但应该在任何其他时间继续发出值。

因此,我认为我可以为UIApplication.significantTimeChangeNotification通知使用NotificationCenter发布者,并将其与我的发布者组合在一起,这样组合排放过程将在数据更改或日期更改时重新运行,从而重新评估地图过滤器。请参阅下面代码的大致轮廓。

问题是NotificationCenter在设置时没有发布事件,因此,以下map等调用实际上都没有评估。merge(with:)不能工作,因为两个发布者发布不同的类型,但combineLatest(_:)zip(_:)都不会发出事件,直到两个发布者都发出了一个事件。

我可以通过在这段代码之后添加NotificationCenter.default.post(name: UIApplication.significantTimeChangeNotification, object: nil)来验证我的代码是否按预期运行,但这是不希望的,因为它可能会向应用程序的其他区域发出信号,当它没有

时,实际时间发生了变化。
private func todaysDate() -> String {
let formatter = DateFormatter()
formatter.dateFormat = "YYYY-MM-dd"
return formatter.string(from: Date())
}
@Published var entities: [MyEntity]
let dayChangePublisher = NotificationCenter.default
.publisher(for: UIApplication.significantTimeChangeNotification)
$entities.combineLatest(dayChangePublisher)
.map(.0) // Only pass on the entity for further operations
.map { entities -> MyEntity? in
let today = todaysDate()
return entities?.first(where: { $0.id == today })
}
...remainder of combine code

这种发布者和事件评估的结合可以在当前的Swift组合框架中实现吗?就像我期望的merge(with:)的行为一样,但是发布者发出两种不同的类型。

编辑:我找到了一个解决方案,我将通知发布者映射到nil数组

let dayChangePublisher = NotificationCenter.default
.publisher(for: UIApplication.significantTimeChangeNotification)
.map { _ ➝ [MyEntity]? in
return nil
}
然后使用mergecompactMap来避免在 上传递任何nil值
let mergedPub = repo.$entities
.merge(with: dayChangePublisher)
.compactMap { entity -> MyEntity? in
let today = todaysDate()
return entities?.first { $0.id == today }
}
.share()

它可以工作,但如果有人有更好的解决方案可能有点麻烦?

如果我理解了你的问题,你需要一个combineLatest,它不会因为没有来自一个发布者的初始值而被阻止。

可以通过.prepend(value)运算符实现。在本例中,因为您不关心实际值,所以首先映射到Void,然后加上Void。它的工作原理如下:

let dayChangePublisher = NotificationCenter.default
.publisher(for: UIApplication.significantTimeChangeNotification)
$entities.combineLatest(
dayChangePublisher
.map { _ in }
.prepend(()) // make sure to prepend a () value
)
.map(.0) // Only pass on the entity for further operations
.map { entities -> MyEntity? in
let today = todaysDate()
return entities?.first(where: { $0.id == today })
}
//... 

相关内容

  • 没有找到相关文章

最新更新