gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-02 16:18:37 25 4
gpt4 key购买 nike

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

因此,我想我可以为 UIApplication.significantTimeChangeNotification 通知使用一个 NotificationCenter 发布者,并将它与我的发布者结合起来,这样结合发射过程就会重新运行在数据更改或日期更改时重新评估 map 过滤器。请参阅下面该代码的粗略概述。

问题是在设置时 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 })
}
//...

关于Swift 合并尚未发送值的发布者,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66075000/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com