You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何NSWorkspace通知与监听器未接收或触发?

问题分析与修复方案

你的代码存在几个关键问题,导致睡眠/唤醒事件完全无法触发:

1. AppDelegate未关联到SwiftUI应用实例

你定义了AppDelegate类,但没有让SwiftUI的NotificationsApp加载这个代理。在macOS的SwiftUI应用中,必须通过@NSApplicationDelegateAdaptor属性包装器关联自定义代理,否则applicationDidFinishLaunching方法永远不会执行,监听器自然无法完成注册。

2. Selector与目标方法不匹配

  • 你用字符串形式的Selector(("sleepListener"))注册监听器,但AppDelegate内的sleepListener是带Notification参数的方法,而全局的sleepListener是无参函数且未标记@objc,系统无法找到正确的目标方法。
  • 你为didWakeNotification注册了wakeUpListener,但AppDelegate内根本没有这个方法,全局的同名函数同样缺少@objc标记,无法被Selector识别。

3. 方法访问权限与语法问题

AppDelegate内的sleepListener被标记为private,虽然加了@objc,但字符串形式的Selector可能无法正确访问;同时使用字符串Selector本身就容易出现拼写错误,不如类型安全的#selector语法可靠。


修复后的完整代码

import SwiftUI

@main
struct NotificationsApp: App {
    // 关联自定义AppDelegate
    @NSApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
    
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
    
    class AppDelegate: NSObject, NSApplicationDelegate {
        
        func applicationDidFinishLaunching(_ aNotification: Notification) {
            // 使用类型安全的#selector语法注册监听器
            let workspaceCenter = NSWorkspace.shared.notificationCenter
            workspaceCenter.addObserver(
                self,
                selector: #selector(sleepListener(_:)),
                name: NSWorkspace.willSleepNotification,
                object: nil
            )
            workspaceCenter.addObserver(
                self,
                selector: #selector(wakeUpListener(_:)),
                name: NSWorkspace.didWakeNotification,
                object: nil
            )
        }

        @objc func sleepListener(_ aNotification: Notification) {
            print("Going to sleep")
        }
        
        @objc func wakeUpListener(_ aNotification: Notification) {
            print("Woke up")
        }
    }
}

额外优化建议

如果想统一处理多个通知,可以注册同一个方法,通过判断通知名称区分事件:

func applicationDidFinishLaunching(_ aNotification: Notification) {
    let workspaceCenter = NSWorkspace.shared.notificationCenter
    workspaceCenter.addObserver(
        self,
        selector: #selector(handleWorkspaceEvent(_:)),
        name: NSWorkspace.willSleepNotification,
        object: nil
    )
    workspaceCenter.addObserver(
        self,
        selector: #selector(handleWorkspaceEvent(_:)),
        name: NSWorkspace.didWakeNotification,
        object: nil
    )
}

@objc func handleWorkspaceEvent(_ aNotification: Notification) {
    switch aNotification.name {
    case NSWorkspace.willSleepNotification:
        print("系统即将进入睡眠")
    case NSWorkspace.didWakeNotification:
        print("系统已唤醒")
    default:
        print("收到未知工作区通知")
    }
}

内容的提问来源于stack exchange,提问作者ian

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 19:16:15