Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

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?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
458 views
Welcome To Ask or Share your Answers For Others

1 Answer

  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...


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...