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

如何用Objective-C检测Mac锁定/睡眠状态?CGSSessionScreenIsLocked疑问

检测Mac锁定/睡眠状态的Objective-C方案

关于CGSSessionScreenIsLocked的状态

CGSSessionScreenIsLocked确实已从CGSessionCopyCurrentDictionary()返回的字典中移除,它属于苹果未公开的API键,后续系统更新中被废弃,因此现在无法通过该键判断屏幕锁定状态。

替代实现方案

1. 基于kCGSessionOnConsoleKey的判断方案

你提到的kCGSessionOnConsoleKey依然有效,其核心逻辑是:当用户不在控制台(屏幕锁定或切换用户)时,该键值为NO。如果只需判断是否处于非活跃锁定状态,可直接使用:

#import <CoreGraphics/CoreGraphics.h>

BOOL isMacLocked() {
    BOOL locked = NO;
    CFDictionaryRef sessionDict = CGSessionCopyCurrentDictionary();
    if (sessionDict) {
        NSNumber *onConsole = (__bridge NSNumber *)CFDictionaryGetValue(sessionDict, kCGSessionOnConsoleKey);
        locked = !onConsole.boolValue;
        CFRelease(sessionDict);
    }
    return locked;
}

注意:该方法会同时识别屏幕锁定和快速用户切换两种场景,若需区分需结合其他逻辑。

2. 实时监听系统通知(精准响应状态变化)

若需要实时捕获锁定/解锁、睡眠/唤醒的状态切换,可通过系统通知实现:

  • 屏幕锁定/解锁:监听com.apple.screenIsLocked和com.apple.screenIsUnlocked分布式通知
  • 睡眠/唤醒:监听NSWorkspace提供的睡眠、唤醒通知

示例代码:

#import <Cocoa/Cocoa.h>

// 注册通知监听
- (void)registerSystemStateNotifications {
    // 监听屏幕锁定/解锁
    [[NSDistributedNotificationCenter defaultCenter] addObserver:self
                                                     selector:@selector(screenLocked:)
                                                         name:@"com.apple.screenIsLocked"
                                                       object:nil];
    [[NSDistributedNotificationCenter defaultCenter] addObserver:self
                                                     selector:@selector(screenUnlocked:)
                                                         name:@"com.apple.screenIsUnlocked"
                                                       object:nil];
    
    // 监听系统睡眠/唤醒
    [[NSWorkspace sharedWorkspace] addObserver:self
                                      selector:@selector(workspaceWillSleep:)
                                          name:NSWorkspaceWillSleepNotification
                                        object:nil];
    [[NSWorkspace sharedWorkspace] addObserver:self
                                      selector:@selector(workspaceDidWake:)
                                          name:NSWorkspaceDidWakeNotification
                                        object:nil];
}

// 状态回调方法
- (void)screenLocked:(NSNotification *)notification {
    // 处理屏幕锁定逻辑
}

- (void)screenUnlocked:(NSNotification *)notification {
    // 处理屏幕解锁逻辑
}

- (void)workspaceWillSleep:(NSNotification *)notification {
    // 处理系统即将睡眠逻辑
}

- (void)workspaceDidWake:(NSNotification *)notification {
    // 处理系统唤醒逻辑
}

// 移除监听(需在对象销毁时调用)
- (void)dealloc {
    [[NSDistributedNotificationCenter defaultCenter] removeObserver:self];
    [[NSWorkspace sharedWorkspace] removeObserver:self];
}

3. 底层IOKit检测睡眠状态

若需要更底层的睡眠状态判断,可使用IOKit框架查询电源管理状态:

#import <IOKit/pwr_mgt/IOPMLib.h>

BOOL isMacAsleep() {
    BOOL asleep = NO;
    io_service_t pmService = IOServiceGetMatchingService(kIOMainPortDefault, IOServiceMatching("IOPMrootDomain"));
    if (pmService) {
        uint32_t powerState = 0;
        IOReturn result = IORegistryEntryCreateCFProperty(pmService, CFSTR("CurrentPowerState"), kCFAllocatorDefault, 0, (CFTypeRef *)&powerState);
        if (result == kIOReturnSuccess) {
            // 0代表唤醒状态,1代表睡眠状态
            asleep = (powerState == 1);
        }
        IOObjectRelease(pmService);
    }
    return asleep;
}

注意事项

  • kCGSessionOnConsoleKey属于官方文档提及的公开会话属性,使用相对安全;
  • 系统通知方案是实时检测状态变化的最优选择,适合需要响应状态切换的场景;
  • IOKit方法需注意沙盒权限配置,部分沙盒应用可能无法正常调用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 01:32:32