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