I'm searching for a way to simulate keystrokes in OSX. I found another solution (Simulate keypress for system wide hotkeys) using Objective-C, but i need to do it with Swift. How can i adapt CGEventCreateKeyboardEvent?
The code on that linked answer is fairly readily convertible to Swift code, however there are a handful of gotchas you will need to take care of along the way:
CGEventSourceCreate takes a
CGEventSourceStateID, which is a typealiase for a
UInt32, but the constants such as
kCGEventSourceStateHIDSystemState are defined as
Int, so you’ll have to cast them i.e.
CGEventSourceStateID(kCGEventSourceStateHIDSystemState). Likewise with
CGEventCreateKeyboardEvent return an
Unmanaged<CGEvent>). The auto-generated Swift API for Core Graphics doesn’t know whether the returned objects need to be released by you or not so you need to check the API docs for these calls and then use
takeUnretainedValue() accordingly on the returned value, to convert them into the underlying type you want to work with.
Finally, they return implicitly unwrapped optionals, so you’ll need to decide if you want to check for nils or just live with the excitement of runtime explosions if they ever return one.
Given all that it’s pretty simple to turn the Objective-C in that answer demonstrating pressing Cmd-Space to Swift, I just tried pasting this into a scratch app and it worked fine:
(though I haven't checked the API docs for whether the retain is the correct thing to do or not)
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)