I’ve created a banner which is being displayed from the bottom of the screen if shouldNewNotifications.count > 0
. Is working fine, but I have one problem with the didSet
. I have a separate screen, and I have also the notifications here that are being displayed in the banner, so I can open them separately. If I open one of these notifications, I have a function that trigger data so the didSet is being called, and the banner is being displayed again. How can I avoid to call this didSet after the banner disappears ? Basically, once the banner was displayed, I only want to see him once.
I only post the code which I consider that is relevant, just you guys to have an ideea.
class NotificationManager: ObservableObject, NotificationManagerManagerSourceProtocol {
public let inAppNotificationsObject = PassthroughSubject<[NotificationItem], Never>()
private var inAppCancelable: AnyCancellable?
private var inAppNotifications: [NotificationItem] = [] {
didSet {
updateActivityRedDot()
updateTabBarDot()
displayInAppBanner()
}
}
init() {
do {
inAppCancelable = inAppNotificationsObject.sink(receiveCompletion: { (_) in
// this inform publisher to "unsubscribe"
self.inAppCancelable?.cancel()
// release canceleble
self.inAppCancelable = nil
// clear stored inAppNotifications
self.inAppNotifications = []
}, receiveValue: { [weak self] notifications in
self?.inAppNotifications = notifications
})
}
}
func removeInAppBanner() {
if let window = DeviceInfo.keyWindow {
if let views = window.viewWithTag(bannerTag) {
views.removeFromSuperview()
}
}
}
func displayInAppBanner() {
if shouldNewNotifications.count > 0 {
if let window = DeviceInfo.keyWindow, let tabBarController = DeviceInfo.keyWindow?.rootViewController as? UITabBarController {
removeInAppBanner()
let view = SoleInAppNotificationBanner(notifications: shouldNewNotifications)
let hostingView = UIHostingController(rootView: view)
let bulletView = NotificationView(view: hostingView.view)
bulletView.tag = bannerTag
tabBarController.view.insertSubview(bulletView, belowSubview: tabBarController.tabBar)
hostingView.view.translatesAutoresizingMaskIntoConstraints = false
hostingView.view.leftAnchor.constraint(equalTo: window.leftAnchor).isActive = true
hostingView.view.rightAnchor.constraint(equalTo: window.rightAnchor).isActive = true
hostingView.view.bottomAnchor.constraint(equalTo: window.bottomAnchor, constant: -tabBarController.tabBar.frame.height).isActive = true
}
}
}
var shouldNewNotifications: [NotificationItem] {
inAppNotifications.filter { $0.category == .should && $0.isNew == true }
}
}
class InAppNotificationsSource: ObservableObject {
@Injected var notificationsUseCase: InAppNotificationsUseCaseProtocol
static let shared = InAppNotificationsSource()
@Published var data: [InAppNotificationsAssetsData]? {
didSet {
NotificationManager.shared.inAppNotificationsObject.send(toNotificationItem(from: data ?? []))
}
}
@MainActor
func patchNotifications(notification: InAppNotificationDetailsAssetsData) async {
if !(notification.isRead) {
do {
readNotification(true, notification: notification)
let notificationData = InAppNotificationsAssetsDataPatch(isRead: true, uuid: notification.uuid)
_ = try await notificationsUseCase.performPatchNotifications(notification: notificationData)
} catch {
readNotification(false, notification: notification)
}
}
}
private func readNotification(_ value: Bool, notification: InAppNotificationDetailsAssetsData) {
data?.indices.filter { data?[$0].uuid == notification.uuid }
.forEach { data?[$0].isRead = value }
self.objectWillChange.send()
}
private func toNotificationItem(from notifications: [InAppNotificationsAssetsData]) -> [NotificationItem] {
var notificationItems: [NotificationItem] = []
notifications.forEach { notification in
let item = NotificationItem(uuid: notification.uuid,
category: notification.category,
priority: notification.priority,
isRead: notification.isRead,
isNew: notification.isNew,
hasBadgeIcon: notification.category == .should,
title: notification.title,
description: notification.previewDescription,
image: notification.imageUrl)
notificationItems.append(item)
}
return notificationItems
}
}
This is what triggers the didSet
.onAppear {
Task {
isLoading = true
notification = try await notificationsUseCase.performGetNotificationDetails(with: selectedNotificationId)
guard let notification = notification else { return }
await inAppNotificationsSource.patchNotifications(notification: notification)
isLoading = false
}
}
I tried to created a boolean
Maria Alexandra is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.