如何在SwiftUI中接收通知中心帖子
我已经看过十几本关于如何使用Combine并接收任务完成通知的教程。似乎它们都显示线性代码——发布者和接收者都在同一个位置,一行接一行 发布通知非常简单,如下代码所示:如何在SwiftUI中接收通知中心帖子,swiftui,publish-subscribe,combine,Swiftui,Publish Subscribe,Combine,我已经看过十几本关于如何使用Combine并接收任务完成通知的教程。似乎它们都显示线性代码——发布者和接收者都在同一个位置,一行接一行 发布通知非常简单,如下代码所示: // background download task complete - notify the appropriate views DispatchQueue.main.async { NotificationCenter.default.post(name: .dataDownloadComplete, objec
// background download task complete - notify the appropriate views
DispatchQueue.main.async {
NotificationCenter.default.post(name: .dataDownloadComplete, object: self, userInfo: self.dataCounts)
}
extension Notification.Name {
static let dataDownloadComplete = Notification.Name("dataDownloadComplete")
}
SwiftUI有onReceive()
修饰符,但我找不到任何方法将上述内容连接到发布通知的“侦听器”
视图
如何接收此通知
仅供参考,经过几天的阅读和整理,我发现了这两种接收通知的方法。为方便起见,它们包含在同一视图中。(省略了一些不相关的细节。)
在我的例子中,获取(在后台线程上执行)是将信息批量加载到多个实体的核心数据中。获取完成后,未更新视图
// in the background fetch download class
...
var dataCounts: [DataSources.Source : Int] = [:]
...
// as each source of data has been imported
self.dataCounts[source] = numberArray.count
...
// in a view
import Combine
struct FilteredPurchasesView: View {
private var downloadCompletePublisher: AnyPublisher<Notification, Never> {
NotificationCenter.default
.publisher(for: .dataDownloadComplete)
.eraseToAnyPublisher()
}
private var publisher = NotificationCenter.default
.publisher(for: .dataDownloadComplete)
.map { notification in
return notification.userInfo as! [DataSources.Source : Int]
}
.receive(on: RunLoop.main)
var body: some View {
List {
ForEach(numbers.indices, id: \.self) { i in
NavigationLink(destination: NumberDetailView(number: numbers[i])) {
NumberRowView(number: numbers[i])
}
.id(i)
}
}
.add(SearchBar(searchText: $numberState.searchText))
.onReceive(downloadCompletePublisher) { notification in
print("dataDownload complete (FilteredPurchasesView 1)")
if let info = notification.userInfo as? [DataSources.Source:Int], let purchaseCount = info[DataSources.Source.purchased] {
if purchaseCount > 0 {
// now the view can be updated/redrawn
} else {
print("purchase update count = 0")
}
}
}
.onReceive(publisher) { notification in
print("dataDownload complete (FilteredPurchasesView 2)")
}
}
}
//在后台获取下载类中
...
var数据计数:[DataSources.Source:Int]=[:]
...
//因为每个数据源都已导入
self.dataCounts[源]=numberArray.count
...
//看来
进口联合收割机
结构FilteredPurchaseView:视图{
private var downloadCompletePublisher:AnyPublisher{
NotificationCenter.default
.publisher(用于:.dataDownloadComplete)
.删除任何发布者()
}
private var publisher=NotificationCenter.default
.publisher(用于:.dataDownloadComplete)
.map{中的通知
返回notification.userInfo as![DataSources.Source:Int]
}
.receive(打开:RunLoop.main)
var body:一些观点{
名单{
ForEach(numbers.index,id:\.self){i in
导航链接(目的地:NumberDetailView(编号:编号[i])){
NumberRowView(编号:编号[i])
}
.id(i)
}
}
.add(搜索栏(搜索文本:$numberState.searchText))
.onReceive(downloadCompletePublisher){中的通知
打印(“数据下载完成(FilteredPurchaseView 1)”)
如果let info=notification.userInfo as?[DataSources.Source:Int],则let purchaseCount=info[DataSources.Source.purchased]{
如果purchaseCount>0{
//现在可以更新/重画视图
}否则{
打印(“采购更新计数=0”)
}
}
}
.onReceive(发布者){中的通知
打印(“数据下载完成(FilteredPurchaseView 2)”)
}
}
}
关于这一点,请注意:
onReceive()
修饰符都包含通知欢迎评论、想法和反馈。这是否回答了您的问题@pawello2222感谢您的链接。那是我看到的一页,让我找到了正确的方向。