macOS SwiftUI应用如何实现前台/后台模拟全局键盘快捷键触发
可行实现方案
你提到的NSEvent.addGlobalMonitorForEvents接口仅用于监听全局键盘事件,无法实现主动触发快捷键的需求,你可以通过以下两种方案实现模拟全局快捷键的需求。
前置要求:开启辅助功能权限
两种方案都需要应用获得系统的辅助功能权限,否则无法向其他应用窗口发送模拟输入事件。你可以用以下代码提前检测权限,无权限时系统会自动弹出引导提示:
import Accessibility func checkAccessibilityPermission() -> Bool { let promptOption = [kAXTrustedCheckOptionPrompt.takeUnretainedValue(): true] as CFDictionary return AXIsProcessTrustedWithOptions(promptOption) }
用户需要在「系统设置>隐私与安全性>辅助功能」中,为你的应用开启权限。
方案1:Core Graphics的CGEvent模拟(推荐)
该方案性能最高、延迟最低,适合高频触发的场景,核心逻辑是手动创建键盘按下、抬起事件并全局分发。
核心实现代码
import CoreGraphics /// 模拟全局快捷键 /// - Parameters: /// - keyCode: 按键的虚拟键码,常用字符键可查<HIToolbox/Events.h>中的kVK_ANSI_*定义 /// - modifiers: 修饰符,比如Command对应.maskCommand,Option对应.maskAlternate,Shift对应.maskShift func simulateGlobalShortcut(keyCode: CGKeyCode, modifiers: CGEventFlags) { // 创建按键按下事件 guard let keyDownEvent = CGEvent(keyboardEventSource: nil, virtualKey: keyCode, keyDown: true) else { return } keyDownEvent.flags = modifiers // 创建按键抬起事件 guard let keyUpEvent = CGEvent(keyboardEventSource: nil, virtualKey: keyCode, keyDown: false) else { return } keyUpEvent.flags = modifiers // 全局发送事件 keyDownEvent.post(tap: .cghidEventTap) keyUpEvent.post(tap: .cghidEventTap) } // 调用示例:模拟Command+V粘贴 simulateGlobalShortcut(keyCode: 9, modifiers: .maskCommand) // 9对应kVK_ANSI_V
常用虚拟键码参考
- V键:9
- C键:8
- A键:0
- Z键:6
- 空格键:49
方案2:AppleScript调用(适合简单场景)
如果需求场景简单,不需要高频触发,可以通过调用AppleScript实现,代码更简洁:
func simulatePasteByAppleScript() { let script = "tell application \"System Events\" to keystroke \"v\" using {command down}" var error: NSDictionary? NSAppleScript(source: script)?.executeAndReturnError(&error) if let error = error { print("执行失败:\(error)") } }
注意事项
- 如果需要应用长期后台驻留,可在Info.plist中添加
LSUIElement字段并设置为true,让应用作为后台UI组件运行,不会显示在Dock栏中,默认不会被系统挂起。 - 如需适配多语言键盘布局,不要写死键码,需通过
UCKeyTranslate接口根据当前系统键盘布局动态转换字符对应的虚拟键码。 - 若应用需要上架App Store,审核时需要明确说明辅助功能权限的使用场景,否则可能会被拒绝。
内容的提问来源于stack exchange,提问作者Lloyd English
相关产品推荐
相关产品推荐

