我有这个问题:在我的主屏幕上,我有一个通知铃声(只显示存储在核心数据中的本地通知),我可以按下它并发送到通知屏幕.如果我收到新的通知--铃声顶部出现红色徽章,则表示我有未读通知.我做了一家出版商,从核心数据中获取未读通知,并计算它们的数量.如果计数大于1,我会出示红色徽章.以下是代码:

 public func fetchCountPublisher<T: PersistentModel>(_ type: T.Type,
                                                        predicate: NSPredicate?) -> AnyPublisher<Int, Error> {
       //request creating code...
        request.predicate = predicate
        
        let count = try? context.count(for: request)
        return Just(count)
            .compactMap { $0 }
            .setFailureType(to: Error.self)
            .eraseToAnyPublisher()
    }

如您所见,我在这里返回一个只有一次有效的发布者.然而,这对我的情况是不正确的. 我将向您展示我的完整代码并解释问题:

 public func hasUnreadNotifications() -> AnyPublisher<Int, Error> {
        repository.fetchCountPublisher(
            LocalNotificationCD.self,
            predicate: \LocalNotificationCD.isUnread == true
        )
    }

我的通知管理器中的代码,它获取未读通知的计数.我将在我的交互程序中使用此方法:

//some DI stuff and other publishers
var hasUnreadNotificationsPublisher: AnyPublisher<Bool, Error> {
        localNotificationsManager.hasUnreadNotifications()
            .map { $0 > 1 ? true : false }
            .eraseToAnyPublisher()
    }

使用这个.map运算符,我将Int发布程序映射到Bool.接下来,在我的视图模型中使用此发布器:

final class HomeViewModelState: ObservableObject {
    @Published var hasUnreadNotifications: Bool = false
}

protocol HomeViewModelProtocol {
    var state: HomeViewModelState { get }
}

final class HomeViewModel {
    // MARK: Public
    let state: HomeViewModelState
    
    //other properties, initializer and DI...
    init() {
        binding()
    }
    
    func binding() {
        interactor.hasUnreadNotificationsPublisher
            .sink(receiveCompletion: { _ in },
                  receiveValue: { [weak self] hasUnreadNotifications in
                self?.state.hasUnreadNotifications = hasUnreadNotifications
            })
            .store(in: &cancellables)
    }
}

从视图模型中,我在我的视图控制器中获得它:

class HomeViewController: UIViewController {
    private var viewModel: HomeViewModelProtocol
    
    // DI
    //binding called in viewDidLoad
    
    private func binding() {
        viewModel.state.$hasUnreadNotifications
            .sink { [weak self] hasUnreadNotifications in
                self?.badgeView.isHidden = !hasUnreadNotifications // не обновляет юай
            }
            .store(in: &cancellables)
    }
}

The problem is that, when I first launch my app, core data fetches the count of the unread notifications and correctly indicates weather there are unread notifications, however, after reading them (they are marked as read when you scroll the notifications list) the unread indicator still remains there. It does not go anywhere until you fully close your app. The binding method is triggered only once since it's in the viewDidLoad method. I think that using Just in the Core Data layer is not really ok for my case because it only works once... What do I do to properly subscribe to the hasUnreadNotifications property and autoupdate the UI? I don't want to do the binding stuff in viewDidAppear.
Thanks in advance.

推荐答案

问题是,你什么时候知道你有新的通知?哪些事件应触发管道发出新的alert 计数?

我怀疑您想要做的是监视NSMangedObjectContext,并在上下文中有新的alert 时报告它们.由于我没有你的完整申请,我的目标是:

let alertPublisher = NotificationCenter.default.publisher(for: .NSManagedObjectContextDidSave)
    .tryCompactMap( { _ in
        // Run the predicate count the results
        // return the count, throw errors on errors etc.
    })
    .eraseToAnyPublisher()

当通知中心发送上下文已保存的通知时,将该通知转换为存在的alert 数量的计数并发布该计数.

react 性管道将一件事变成另一件事.在本例中,您希望将alert 数量可能已更改的某些指示转换为这些alert 的具体计数.您必须根据您的应用程序域 Select 发起事件.

Ios相关问答推荐

如何让AVAudio.installTap()每秒回调125次

彩色进度线--SWIFT

如何修复使用EFCore和SQLite的.Net MAUI iOS应用程序上的当前应用程序不支持NullabilityInfoContext?

当重新呈现UI时,嵌套的 struct 值如何与@Observable一起工作?

如何在SwiftUI中基于嵌套视图中的状态动态显示外部视图的内容?

带菜单的选取器不适用于Int32,但适用于Int

SwiftUI - 搜索栏和导航标题之间的空间太大

使用 Objective-C 创建 iOS 框架

仅更改 AttributedString 的字符串(例如 UIButton 配置 attributeTitle)

在 iOS 上启用明文本地流量在 .NET MAUI 中不起作用

如何为 XCTest、SwiftUI 预览等初始化带有 @MainActor 注释的 Swift 类

xcode-select:找不到clang

将值传递给导航链接视图中的文本框

向左或向右移动时如何水平翻转sprite?

NSURLConnection 的 Xcode 4 警告未使用表达式结果

改变 UIView 位置的简单方法?

用 PC 调试 ipad safari

如何从 UIPickerView 获取选定的值

iOS SDK - 以编程方式生成 PDF 文件

你如何以编程方式从视图控制器中画一条线?