Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Defining and executing simple AppleScript commands in a Cocoa app

I'm trying to add some scripting functionality to a Cocoa app that I've written. I've created an sdef (Scripting Definition File) for my project. So far I have been successful in accessing object children (elements) with AppleScript but I cannot for the life of me figure out how to call methods (commands).

Here is my sdef file.

<suite name="mySuite" code="mSUI" description="My Application Suite">
    <class name="application" code="capp" description="Top level scripting object.">
        <cocoa class="NSApplication"/>
        <!-- I can access these elements fine -->
        <element description="Test children." type="child" access="r">
            <cocoa key="myChildren"/>
        </element>
        <!-- Cannot seem to call this method :( -->
        <responds-to command="testmethod">
            <cocoa method="exposedMethod:"/>
        </responds-to>
    </class>
    <class name="child" code="cHIL" description="A Child." plural="children">
        <cocoa class="Child"/>
        <property name="name" code="pnam" description="The child name." type="text" access="r">
            <cocoa key="name"/>
        </property>
    </class>
    <command name="testmethod" code="tEST" description="Execute the test method" />
</suite>

Here are my controller class implementations (this is the delegate of my application)

MyController.h

#import <Cocoa/Cocoa.h>

@interface MyController : NSObject {
    NSMutableArray* myChildren;
}
// Some Methods

@end

MyController+Scripting.m

#import "MyController+Scripting.h"

@implementation MyController (Scripting)

// This works when I'm accessing the myChildren 
- (BOOL)application:(NSApplication*)sender delegateHandlesKey:(NSString*)key { 
    NSLog(@"Key = %@", key);
  return ([key isEqualToString:@"myChildren"]);
}
// This does NOT work...
- (void)exposedMethod:(NSScriptCommand*)command {
    NSLog(@"Invoked Test Script Method %@", [command description]);
}

@end

Lastly, the AppleScript I am trying is:

tell application "MyApplication"
    testmethod
end tell

which responds with "AppleScript Error - The variable testmethod is not defined."

Any ideas what I'm doing wrong here? I feel like I'm missing something simple but my Googling doesn't seem to be turning up anything helpful.

like image 491
nrj Avatar asked Jul 23 '09 18:07

nrj


3 Answers

Things look mostly right, but the code for the <command/> should be a two-part code (eight characters) and not four.

like image 143
Ben Stiglitz Avatar answered Nov 01 '22 05:11

Ben Stiglitz


I just posted a detailed solution on how to add a command with argument here: https://stackoverflow.com/a/10773994/388412

In short: I think you should subclass NSScriptCommand and override -(void)performDefaultImplementation rather than exposing a method in your controller. At least that's what I distilled from the docs:

"This command is a subclass of NSScriptCommand, containing one method, performDefaultImplementation. That method overrides the version in NSScriptCommand"

… and it works fine for me, see my linked answer for details.

like image 35
auco Avatar answered Nov 01 '22 03:11

auco


(I've actually never added scriptability to a Cocoa app, so take my stab in the dark with a grain of salt.)

The first thing I would guess is that exposedMethod: takes a parameter, but I don't see where one might be specified in your sdef or AppleScript. In fact, it looks like AppleScript is treating testmethod as a variable, not a command. (Maybe it should be something like "testmethod with ..." instead?) You may need to define a <parameter> or <direct-parameter> element for the command in the sdef.

Also, wouldn't you need an object to call the method on? Since your controller is the application delegate, I'm not sure of the intricacies there, but might AppleScript try to invoke testMethod: on NSApplication instead of your delegate?

I'm guessing you've looked at Apple's sample code and other resources, but if not, here are a few links that may help:

  • Introduction to Cocoa Scripting Guide
  • TechNote 2106: Scripting Interface Guidelines
  • http://developer.apple.com/samplecode/SimpleScriptingObjects/
  • http://developer.apple.com/samplecode/SimpleScriptingPlugin/
  • http://www.shadowlab.org/softwares/SdefEditor/sdef-format.html

Good luck!

like image 33
Quinn Taylor Avatar answered Nov 01 '22 03:11

Quinn Taylor