Send keystrokes to frontmost app from sandboxed cocoa app

后端 未结 1 1137
悲哀的现实
悲哀的现实 2021-02-13 12:15

I need to send keystrokes to front most app from my cooca app.

I already have working code for it by using CGEventCreateKeyboardEvent() and AXUIElemen

1条回答
  •  慢半拍i
    慢半拍i (楼主)
    2021-02-13 12:51

    This is actually possible. I have made an example app available here - SendKey at GitHub

    I took the easy road and started with a simple AppleScript:

    delay 5
    
    tell application "System Events"
        repeat 10 times
            keystroke "#"
        end repeat
    end tell
    

    The 'delay' in the script simply gives me enough time to make a text editor the frontmost application. I would suggest starting with just running this script to see what it does.

    Then, I created an Xcode project using the default Application template and wrote:

    - (void)applicationDidFinishLaunching:(NSNotification *)aNotification
    {
        NSString*       scriptPath  = [[NSBundle mainBundle] pathForResource:@"sendkey" ofType:@"scpt"];
        NSURL*          scriptURL   = [NSURL fileURLWithPath:scriptPath];
        NSDictionary*   errors;
        NSAppleScript*  script      = [[NSAppleScript alloc] initWithContentsOfURL:scriptURL error:&errors];
    
        NSLog( @"%@", errors );
    
        [script executeAndReturnError:&errors];
    
        NSLog( @"%@", errors );
    }
    

    I tested this without turning on sandboxing to verified it works and it did. Then I turned on Sandboxing and, of course, it broke. But, fortunately, there is a way around that. For now, Apple is providing a temporary entitlement called com.apple.security.temporary-exception.apple-events. And, you can request the exception be granted for 'com.apple.systemevents'. This is what my entitlements file looks like:

    
    
    
      
        com.apple.security.temporary-exception.apple-events
        
          com.apple.systemevents
        
        com.apple.security.app-sandbox
        
      
    
    

    Once I added this entitlement to my sandboxed app and signed it, it worked as expected again.

    Now, if you want to send other keys, this question & answer will demonstrate how to build your script on the fly - Passing variables to an applescript.

    Of course, once you have all of these working, you can probably turn to NSAppleEventDescriptor and related classes to build the event in code, but I haven't played with that technique.

    Please note that Apple does suggest you do the following when using a temporary entitlement:

    If you choose not to sandbox your app now or to use a temporary exception entitlement, use Apple’s bug reporting system to let Apple know about the issue you are encountering. Apple considers feature requests as it develops the OS X platform. Also, be sure use the Review Notes field in iTunes Connect to explain why the exception is needed.

    0 讨论(0)
提交回复
热议问题