如何获取其他macOS应用的Dock徽章计数并监控系统通知事件?
获取macOS应用徽章计数与监控系统通知
获取运行中应用的徽章计数
直接通过NSWorkspace遍历所有运行中的应用,读取NSRunningApplication的badgeCount属性即可拿到对应应用的徽章数值:
import AppKit func fetchRunningAppsBadgeData() -> [(appName: String, bundleID: String, badgeCount: Int)] { let workspace = NSWorkspace.shared // 过滤掉系统禁止激活的后台进程 let validApps = workspace.runningApplications.filter { $0.activationPolicy != .prohibited } return validApps.compactMap { app in guard let appName = app.localizedName, let bundleID = app.bundleIdentifier else { return nil } return (appName, bundleID, app.badgeCount) } }
如果需要实时监控单个应用的徽章计数变化,可以使用KVO监听badgeCount属性:
// 监听指定应用的徽章变化示例 if let targetApp = NSWorkspace.shared.runningApplications.first(where: { $0.bundleIdentifier == "com.apple.Mail" }) { targetApp.addObserver(self, forKeyPath: #keyPath(NSRunningApplication.badgeCount), options: [.old, .new], context: nil) } // 实现KVO回调 override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) { guard keyPath == #keyPath(NSRunningApplication.badgeCount), let app = object as? NSRunningApplication else { super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context) return } let newCount = change?[.newKey] as? Int ?? 0 // 这里更新你的红点UI }
监控系统通知事件
有两种可靠方案实现系统通知的监听,按需选择:
方案1:UserNotifications框架(推荐)
通过UNUserNotificationCenter及其代理方法监听通知投递与用户交互事件,需要先申请通知权限:
import UserNotifications class NotificationTracker: NSObject, UNUserNotificationCenterDelegate { override init() { super.init() let center = UNUserNotificationCenter.current() center.delegate = self // 请求通知权限 center.requestAuthorization(options: [.alert, .badge, .sound]) { granted, _ in if granted { // 权限获取成功,开始监听 } } } // 前台收到通知时触发 func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) { let appBundleID = notification.request.content.categoryIdentifier let notificationTitle = notification.request.content.title // 根据bundleID更新对应应用的红点 updateAppBadgeIndicator(bundleID: appBundleID) completionHandler([.badge]) } // 用户点击通知时触发 func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) { let appBundleID = response.notification.request.content.categoryIdentifier // 处理点击后的逻辑,比如清除红点 clearAppBadgeIndicator(bundleID: appBundleID) completionHandler() } private func updateAppBadgeIndicator(bundleID: String) { // 实现你的红点更新逻辑 } private func clearAppBadgeIndicator(bundleID: String) { // 实现红点清除逻辑 } }
方案2:分布式通知监听
通过NSDistributedNotificationCenter监听系统分发的通知投递事件,无需UserNotifications权限,但需要解析系统传递的通知数据:
import Foundation class DistributedNotificationWatcher { private var observer: NSObjectProtocol? init() { let center = NSDistributedNotificationCenter.default() observer = center.addObserver(forName: NSNotification.Name("com.apple.notificationcenter.delivered"), object: nil, queue: .main) { notification in guard let userInfo = notification.userInfo, let appBundleID = userInfo["bundleID"] as? String, let content = userInfo["content"] as? [String: Any] else { return } let title = content["title"] as? String ?? "" print("收到来自\(appBundleID)的通知:\(title)") // 更新对应应用的红点 self.updateBadgeForApp(bundleID: appBundleID) } } deinit { if let observer = observer { NSDistributedNotificationCenter.default().removeObserver(observer) } } private func updateBadgeForApp(bundleID: String) { // 实现你的红点更新逻辑 } }
注意事项
- 权限配置:你的应用需要在系统「隐私与安全性」→「通知」中开启通知访问权限,否则无法监听或获取完整的通知数据。
- 数据同步:监听通知后,建议结合前面的徽章计数获取方法,定期同步最新的徽章数值,避免通知监听遗漏导致的红点不准确。
内容的提问来源于stack exchange,提问作者J brian
相关产品推荐
相关产品推荐

