斯威夫特联合出版社(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,嗯…,我想它不需要显式地传递参数
()
aka
Void
,我只是尝试了
prepend()
,我认为它没有发送。但是我只试过一次,而且
.prepend(())
可以工作,所以无论如何都要坚持。如果调用
prepend()
而不传递参数,它的计算结果将是一个空的变量列表
()
,然后它会进行预处理,但由于它是空的,所以在功能上它是非操作的。因为
()
(或者单位,如果你愿意的话)与任何其他类型一样,即使它有一个单数值,也需要显式传递该值。@CharlesMaria,啊。。你们都是对的。抢手货在
预结束
中缺少一个开口括号。应该是
.prepend(())
,很容易修复,但只是以防万一一些出现并复制code@DamienPontifex,嗯…,我想它不需要显式地传递参数
()
aka
Void
,我只是尝试了
prepend()
,我认为它没有发送。但是我只试过一次,而且
.prepend(())
可以工作,所以无论如何都要坚持。如果调用
prepend()
而不传递参数,它的计算结果将是一个空的变量列表
()
,然后它会进行预处理,但由于它是空的,所以在功能上它是非操作的。因为
()
(或者单位,如果你愿意的话)与任何其他类型一样,即使它有一个单数值,也需要显式传递该值。@CharlesMaria,啊。。你们都是对的。抢手货