swift - Swift 合并尚未发送值的发布者
问题描述
我有一个发布者需要重新评估一天的变化,但应该在任何其他时间继续发出值。
因此,我认为我可以将NotificationCenter
发布者用于UIApplication.significantTimeChangeNotification
通知并将其与我的发布者结合起来,这样组合发射过程将在数据更改或日期更改时重新运行,从而重新评估地图过滤器。请参阅下面该代码的粗略轮廓。
问题是在设置的时间点没有发布事件NotificationCenter
,因此,以下map
etc 调用都没有实际评估。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
}
然后使用merge
andcompactMap
来避免传递任何 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 })
}
//...
推荐阅读
- javascript - 如何在提交时使用 jquery 验证来验证表单?
- python-3.x - 如何划分对象列表中的两个元素?
- reactjs - 如何防止 react-router-dom 嵌套路由与路由参数混淆
- tron - 如何使用 trongrid api 过滤器参数获取合同事件?
- css - 如何在所有屏幕中增加 div 高度?
- git - Github 上的双重用户名
- python - 有没有办法使用熊猫根据其他条件从两个不同的列和跨行对日期进行分组?
- java - KubernetesClientException:操作:[list] for kind:[Endpoints] with name: [null] in namespace: [null] failed
- flutter - DART:显示选定的联系人
- wireless - 客户端发送 ABORT 以响应 SCTP INIT ACK