斯威夫特联合出版社(Swift combine publishers),其中一家还没有';我还没有发一个值
我有一个出版商,它需要在日变化时重新评估,但应该在任何其他时间继续发布值 因此,我认为我可以使用斯威夫特联合出版社(Swift combine publishers),其中一家还没有';我还没有发一个值,swift,combine,Swift,Combine,我有一个出版商,它需要在日变化时重新评估,但应该在任何其他时间继续发布值 因此,我认为我可以使用NotificationCenter发布者发布ui应用程序.significtTimeChangeNotification通知,并将其与我的发布者合并,以便在数据更改或日期更改时重新运行合并排放过程,从而重新评估地图过滤器。请参见下面的代码概要 问题是在设置时,NotificationCenter没有发布事件,因此,以下mapetc调用都没有实际计算merge(with:)不起作用,因为这两个发布服务
NotificationCenter
发布者发布ui应用程序.significtTimeChangeNotification
通知,并将其与我的发布者合并,以便在数据更改或日期更改时重新运行合并排放过程,从而重新评估地图过滤器。请参见下面的代码概要
问题是在设置时,NotificationCenter
没有发布事件,因此,以下map
etc调用都没有实际计算merge(with:)
不起作用,因为这两个发布服务器发布了不同的类型,但是CombineTest(:)
和zip(:)
在两个发布服务器都发出单个事件之前都不会发出事件
我可以通过在此代码之后添加NotificationCenter.default.post(名称:UIApplication.SignificationTimeChangeNotification,对象:nil)
来验证我的代码是否按预期运行,但这是不可取的,因为它可能会向应用程序的其他区域发出信号,表明实际时间发生了变化,而实际时间并未发生变化
private func todaysDate()->String{
let formatter=DateFormatter()
formatter.dateFormat=“YYYY-MM-dd”
返回格式化程序.string(起始日期())
}
@已发布的var实体:[MyEntity]
让dayChangePublisher=NotificationCenter.default
.publisher(适用于:UIApplication.SignificationTimeChangeNotification)
$entities.CombineTest(dayChangePublisher)
.map(\.0)//仅传递实体以进行进一步操作
.map{entities->MyEntity?in
让我们今天=今天
返回实体?.first(其中:{$0.id==today})
}
…联合收割机代码的剩余部分
在当前的Swift combine框架中,发布者和事件评估的结合是否可以实现?就像我期望的merge(with:)
的行为,但是发布者发出两种不同的类型
编辑:
我找到了一个将通知发布服务器映射到nil数组的解决方案
let dayChangePublisher=NotificationCenter.default
.publisher(适用于:UIApplication.SignificationTimeChangeNotification)
.map{u➝ [我的实体]?在
归零
}
然后使用merge
和compactMap
避免在
让mergedPub=repo.$entities
.merge(与:dayChangePublisher合并)
.compactMap{entity->MyEntity?在
让我们今天=今天
返回实体?.first{$0.id==today}
}
.share()
它可以工作,但如果有人有更好的解决方案,可能会有点麻烦?如果我理解你的问题,你需要一个
combinelatetest
,它不会因为没有来自某个发布者的初始值而被阻止
您可以使用.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 })
}
//...
如果我理解您的问题,您需要一个
combinelateest
,它不会因为没有来自某个发布者的初始值而被阻止
您可以使用.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 })
}
//...
在
预结束
中缺少一个开口括号。应该是.prepend(())
,很容易修复,但只是以防万一一些出现并复制code@DamienPontifex,嗯…,我想它不需要显式地传递参数()
akaVoid
,我只是尝试了prepend()
,我认为它没有发送。但是我只试过一次,而且.prepend(())
可以工作,所以无论如何都要坚持。如果调用prepend()
而不传递参数,它的计算结果将是一个空的变量列表()
,然后它会进行预处理,但由于它是空的,所以在功能上它是非操作的。因为()
(或者单位,如果你愿意的话)与任何其他类型一样,即使它有一个单数值,也需要显式传递该值。@CharlesMaria,啊。。你们都是对的。抢手货在预结束
中缺少一个开口括号。应该是.prepend(())
,很容易修复,但只是以防万一一些出现并复制code@DamienPontifex,嗯…,我想它不需要显式地传递参数()
akaVoid
,我只是尝试了prepend()
,我认为它没有发送。但是我只试过一次,而且.prepend(())
可以工作,所以无论如何都要坚持。如果调用prepend()
而不传递参数,它的计算结果将是一个空的变量列表()
,然后它会进行预处理,但由于它是空的,所以在功能上它是非操作的。因为()
(或者单位,如果你愿意的话)与任何其他类型一样,即使它有一个单数值,也需要显式传递该值。@CharlesMaria,啊。。你们都是对的。抢手货