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

Mac沙盒环境下如何检测键盘按键动作(无需获取按键数据)

沙盒环境下监测用户键盘活跃的可行方案

你当前的全局键盘事件监测在沙盒开启时失效,是因为NSEvent.addGlobalMonitorForEvents在沙盒限制下无法捕获跨应用的键盘事件。而你仅需判断用户是否有按键操作、不需要具体按键数据,完全可以用以下符合App Store沙盒规范的方案:

使用CGEventSource查询用户活跃时间

CoreGraphics框架中的CGEventSource提供了无需捕获具体事件、仅查询系统层面用户最后活跃时间的API,这个API在沙盒环境下完全可用,且不涉及隐私数据获取。

核心思路

定时查询系统记录的最后一次键盘/鼠标事件发生的时间,若时间间隔小于设定的阈值(比如1秒),则判定用户处于活跃状态,重置你的activityTimer。

代码实现

替换你原有的monitorKeyboardActivity函数,新增定时查询逻辑:

import CoreGraphics

// 定时查询用户活跃状态的计时器
var activityCheckTimer: Timer?

func startActivityMonitoring() {
    // 保留原有鼠标监测逻辑
    monitorMouseActivity()
    
    // 启动定时活跃查询(间隔可按需调整,建议1-2秒)
    activityCheckTimer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { [weak self] _ in
        self?.checkUserActivity()
    }
}

func checkUserActivity() {
    let eventSource = CGEventSource(stateID: .hidSystemState)
    
    // 查询最后一次键盘事件的间隔(秒)
    let lastKeyboardInterval = eventSource?.secondsSinceLastEventType(.keyDown) ?? Double.infinity
    // 查询最后一次鼠标事件的间隔(秒)
    let lastMouseInterval = eventSource?.secondsSinceLastEventType(.mouseMoved) ?? Double.infinity
    
    // 若键盘或鼠标事件在1秒内发生过,判定为活跃
    if lastKeyboardInterval < 1.0 || lastMouseInterval < 1.0 {
        resetActivityTimer()
    }
}

// 保留你原有的鼠标监测函数
func monitorMouseActivity() {
    NSEvent.addGlobalMonitorForEvents(matching: [.mouseMoved]) { _ in
        resetActivityTimer()
    }
    NSEvent.addGlobalMonitorForEvents(matching: [.leftMouseDown, .rightMouseDown, .otherMouseDown]) { _ in
        resetActivityTimer()
    }
}

方案优势

  • 完全符合App Store沙盒要求,无需禁用沙盒即可上架
  • 不捕获任何具体按键/鼠标数据,仅查询时间间隔,无隐私风险
  • 逻辑简单,性能开销低,定时查询间隔可根据需求灵活调整

注意事项

  • 应用启动时调用startActivityMonitoring(),退出时记得销毁activityCheckTimer避免内存泄漏
  • secondsSinceLastEventType返回的是相对于当前时间的间隔,判断阈值可根据你的活跃判定逻辑调整

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 04:46:15