Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I add Applescript support to my Cocoa application?

I am new to the world of Cocoa programming, and I want to add Applescript support to my application. The examples at Apple's website seem out of date.

How do I add Applescript support to my Cocoa application?

like image 964
shreyasva Avatar asked Mar 19 '10 18:03

shreyasva


People also ask

Does Xcode support AppleScript?

Since the AppleScript Studio frameworks from Mac OS X v. 10.5 are included with Mac OS X v. 10.6, existing Studio projects remain editable in Xcode.


1 Answers

  1. If you want to send AppleScript from your application and need a sandboxed app, you need to create a temporary entitlement

  2. You need to add those two keys in your info.plist

    <key>NSAppleScriptEnabled</key> <true/> <key>OSAScriptingDefinition</key> <string>MyAppName.sdef</string> 

...of course you have to change "MyAppName" to your app's name

  1. Create a .sdef file and add it to your project. The further course now greatly depends on the needs of your application, there are:

    1. Class Elements (create an object from AppleScript)
    2. Command Elements (override NSScriptCommand and execute "verb-like" commands)
    3. Enumeration Elements
    4. Record-Type Elements
    5. Value-Type Elements (KVC)
    6. Cocoa Elements

    -

    Go here to find a detailed description and many details on their implementation: https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/ScriptableCocoaApplications/SApps_script_cmds/SAppsScriptCmds.html

  2. I found working with Class and KVC Elements very complicated, as I just wanted to execute a single command, nothing fancy. So in order to help others, here's an example of how to create a new simple command with one argument. In this example it'll "lookup" one string like this:

    tell application "MyAppName"     lookup "some string" end tell 
  3. The .sdef file for this command looks like this:

    <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE dictionary SYSTEM "file://localhost/System/Library/DTDs/sdef.dtd">  <dictionary title="MyAppName">     <suite name="MyAppName Suite" code="MApN" description="MyAppName Scripts">         <command name="lookup" code="lkpstrng" description="Look up a string, searches for an entry">             <cocoa class="MyLookupCommand"/>             <direct-parameter description="The string to lookup">                 <type type="text"/>             </direct-parameter>         </command>     </suite> </dictionary> 
  4. Create a subclass of NSScriptCommand and name it MyLookupCommand

    The MyLookupCommand.h

    #import <Foundation/Foundation.h>  @interface MyLookupCommand : NSScriptCommand  @end 

    The MyLookupCommand.m

    #import "MyLookupCommand.h"  @implementation MyLookupCommand  -(id)performDefaultImplementation {      // get the arguments     NSDictionary *args = [self evaluatedArguments];     NSString *stringToSearch = @"";     if(args.count) {         stringToSearch = [args valueForKey:@""];    // get the direct argument     } else {         // raise error         [self setScriptErrorNumber:-50];         [self setScriptErrorString:@"Parameter Error: A Parameter is expected for the verb 'lookup' (You have to specify _what_ you want to lookup!)."];     }     // Implement your code logic (in this example, I'm just posting an internal notification)     [[NSNotificationCenter defaultCenter] postNotificationName:@"AppShouldLookupStringNotification" object:stringToSearch];     return nil; }  @end 

    That's basically it. The secret to this is to subclass NSScriptCommand and override performDefaultImplementation. I hope this helps someone to get it faster...

like image 55
auco Avatar answered Sep 19 '22 14:09

auco