How do I add Applescript support to my Cocoa application?

ε祈祈猫儿з 提交于 2019-12-18 09:59:54

问题


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?


回答1:


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




回答2:


Modern versions of Cocoa can directly interpret the scripting definition (.sdef) property list, so all you need to do for basic AppleScript support is to create the sdef per the docs, add it to your "copy bundle resources" phase and declare AppleScript support in your Info.plist. To access objects other than NSApp, you define object specifiers, so each object knows its position in the scripting world's hierarchy. That gets you kvc manipulation of object properties, and the ability to use object methods as simple script commands.




回答3:


A simple example to get you started,

place a script (named dialog) into the documents folder then you can run it from Xcode

NSArray *arrayPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *docDirectory = [arrayPaths objectAtIndex:0];
    NSString *filePath = [docDirectory stringByAppendingString:@"/dialog.scpt"];

     NSAppleScript *scriptObject = [[NSAppleScript alloc] initWithContentsOfURL:[NSURL fileURLWithPath:filePath] error:nil];

 [scriptObject executeAndReturnError:nil];

The nice thing about keeping the script external is the ability to edit it outside of Xcode. I would recommend adding the error checking if you did start editing as the applescript may not compile

maybe check with

if(scriptObject.isCompiled){


来源:https://stackoverflow.com/questions/2479585/how-do-i-add-applescript-support-to-my-cocoa-application

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!