feat: 接入消息未读数、全部已读与首页红点角标同步。

固定消息中心为首页入口,并在推送到达、已读后刷新桌面角标。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-07-21 18:02:43 +08:00
parent e7f1d777dd
commit caeeb9a1cf
18 changed files with 748 additions and 37 deletions

View File

@ -1,6 +1,32 @@
import UIKit
import UserNotifications
/// App 便
@MainActor
protocol ApplicationIconBadgeSetting: AnyObject {
///
func setBadgeCount(_ count: Int) async
}
/// 使 UserNotifications App
@MainActor
final class SystemApplicationIconBadgeSetter: ApplicationIconBadgeSetting {
///
static let shared = SystemApplicationIconBadgeSetter()
private init() {}
func setBadgeCount(_ count: Int) async {
do {
try await UNUserNotificationCenter.current().setBadgeCount(max(count, 0))
} catch {
#if DEBUG
print("Update application icon badge failed: \(error.localizedDescription)")
#endif
}
}
}
/// SDK 便使
@MainActor
protocol PushSDKProviding: AnyObject {
@ -85,6 +111,7 @@ final class PushNotificationManager: NSObject {
private let appStore: AppStore
private let defaults: UserDefaults
private let router: any PushRouting
private let applicationIconBadgeSetter: any ApplicationIconBadgeSetting
private var isInitialized = false
private var didRequestAuthorization = false
@ -99,13 +126,15 @@ final class PushNotificationManager: NSObject {
api: (any PushRegistrationServing)? = nil,
appStore: AppStore = .shared,
defaults: UserDefaults = .standard,
router: (any PushRouting)? = nil
router: (any PushRouting)? = nil,
applicationIconBadgeSetter: (any ApplicationIconBadgeSetting)? = nil
) {
self.sdk = sdk ?? JPushSDKAdapter()
self.api = api ?? NetworkServices.shared.pushAPI
self.appStore = appStore
self.defaults = defaults
self.router = router ?? PushRouteCoordinator.shared
self.applicationIconBadgeSetter = applicationIconBadgeSetter ?? SystemApplicationIconBadgeSetter.shared
super.init()
}
@ -152,6 +181,12 @@ final class PushNotificationManager: NSObject {
uploadTask = nil
queuedForcedUpload = false
router.resetPendingRoute()
Task { await updateApplicationIconBadgeCount(0) }
}
/// App Icon
func updateApplicationIconBadgeCount(_ count: Int) async {
await applicationIconBadgeSetter.setBadgeCount(max(count, 0))
}
/// App Registration ID
@ -204,6 +239,7 @@ final class PushNotificationManager: NSObject {
///
func handleRemoteNotification(_ userInfo: [AnyHashable: Any]) {
JPUSHService.handleRemoteNotification(userInfo)
NotificationCenter.default.post(name: NotificationName.unreadMessageCountDidChange, object: nil)
}
private func observeJPushNetworkLogin() {
@ -317,6 +353,9 @@ extension PushNotificationManager: JPUSHRegisterDelegate {
withCompletionHandler completionHandler: @escaping (Int) -> Void
) {
JPUSHService.handleRemoteNotification(notification.request.content.userInfo)
Task { @MainActor in
NotificationCenter.default.post(name: NotificationName.unreadMessageCountDidChange, object: nil)
}
let options: UNNotificationPresentationOptions = [.banner, .list, .sound, .badge]
completionHandler(Int(options.rawValue))
}