一尘不染

使用Swift模拟按键

swift

我正在寻找一种在OSX中模拟击键的方法。我发现了使用Objective-C的另一种解决方案针对系统范围的热键模拟按键,但是我需要使用Swift来实现。如何适应CGEventCreateKeyboardEvent?


阅读 338

收藏
2020-07-07

共1个答案

一尘不染

链接答案上的代码可以很容易地转换为Swift代码,但是在此过程中您需要注意一些技巧:

CGEventSourceCreate接受a
CGEventSourceStateID,这是a的类型别名UInt32,但是诸如的常量kCGEventSourceStateHIDSystemState被定义为as
Int,因此您必须将它们强制转换为ie
CGEventSourceStateID(kCGEventSourceStateHIDSystemState)。与相同CGEventFlags

CGEventSourceCreateCGEventCreateKeyboardEvent返回一个Unmanaged<CGEventSource>(或Unmanaged<CGEvent>)。自动生成的用于核心图形的Swift
API不知道您是否需要释放返回的对象,因此您需要检查这些调用的API文档,然后对返回值使用takeRetainedValue()takeUnretainedValue()相应地将其转换为您要使用的基础类型。

最后,它们返回隐式解包的可选变量,因此,您需要确定是否要检查nil,或者如果它们返回一个,则只是在运行时爆炸的刺激下生活。

鉴于在演示中将Objective-C转换为演示将Cmd-Space按下Swift相当简单,我只是尝试将其粘贴到草稿应用程序中,并且效果很好:

(尽管我还没有检查API文档中的保留内容是否正确)

let src = CGEventSourceCreate(CGEventSourceStateID(kCGEventSourceStateHIDSystemState)).takeRetainedValue()

let cmdd = CGEventCreateKeyboardEvent(src, 0x38, true).takeRetainedValue()
let cmdu = CGEventCreateKeyboardEvent(src, 0x38, false).takeRetainedValue()
let spcd = CGEventCreateKeyboardEvent(src, 0x31, true).takeRetainedValue()
let spcu = CGEventCreateKeyboardEvent(src, 0x31, false).takeRetainedValue()

CGEventSetFlags(spcd, CGEventFlags(kCGEventFlagMaskCommand));
CGEventSetFlags(spcd, CGEventFlags(kCGEventFlagMaskCommand));

let loc = CGEventTapLocation(kCGHIDEventTap)

CGEventPost(loc, cmdd)
CGEventPost(loc, spcd)
CGEventPost(loc, spcu)
CGEventPost(loc, cmdu)
2020-07-07