2

I wrote an application that can be scriptable using AppleScript. Now I can write the next thing in AppleScript editor:

tell application "My Magazines"
    current magazine
end tell

It returns the following response:

«class » "The NY Times" of application "My Magazines"

The response is okay. I can extract properties of it and use methods defined in the magazine class. The only thing that bothers me is «class », which is not quite human readable. I tried to find the method I need to override to provide users with better description of the method, but couldn't find one.

Is there a method I can override to replace «class » "The NY Times" with something like Magazine "The NY Times"?

magazine is defined as following in my sdef-file:

<class name="magazine" code="sMAG" description="A particular magazine">
        <cocoa class="MyMagazine" />

        <property name="name" code="pnam" type="text" access="r" description="Title of it">
            <cocoa key="name" />
        </property>
</class>

The class itself is defined as:

@interface MyMagazine : NSObject
{
    NSString *name;
}

@property (nonatomic, readonly) NSString *name;

@end

And implemented like:

@implementation MyMagazine
@synthesize name;

- (NSScriptObjectSpecifier *)objectSpecifier
{
    MyMagazinesList *list = [MyMagazinesList sharedList];

    return [[[NSNameSpecifier alloc] initWithContainerClassDescription:(NSScriptClassDescription *)[[list objectSpecifier] keyClassDescription]
                                               containerSpecifier:[list objectSpecifier]
                                                              key:@"magazines"
                                                             name:name] autorelease];

}

Daniel O'Hara
  • 13,307
  • 3
  • 46
  • 68

3 Answers3

0

You have to create an Applescript Dictionary for the apple events which provides the terminology for the events. Lots of resources out there on creating the sdef file.

jweaks
  • 3,674
  • 1
  • 19
  • 32
  • Of course I have the `sdef` file created. The part of it you can see in my question. What are you particularly talking about? – Daniel O'Hara Jun 15 '14 at 09:29
  • Daniel, sorry, I can't defend my comment. Maybe I posted from my phone and most of your question showing the sdef was below the fold. *shrug* Looks to me like it should be an NSString returned from the command, so not sure why it's a «class » – jweaks Jun 16 '14 at 04:20
0

Your sdef snippet doesn't show how you define the "current magazine" term. It is crucial to get that part right. It should look something like this:

<suite name=...>
  <class name="magazine" code="sMAG" ...>
    <cocoa class="MyMagazine" />
      <property name="name" code="pnam" type="text" access="r" ...>
         <cocoa key="name" />
      </property>
  </class>  

  <class name="application" ...>
    <cocoa class="MyApplication"/>
      <property name="current magazine" code="cMAG" type="magazine" access="r">
        <cocoa key="currentMagazine"/>
      </property>

MyApplication.h should have a

@property MyMagazine *currentMagazine;

Finally, MyMagazine.m needs an -objectSpecifier that converts the MyMagazine* (which will be self when it gets to that method) into a NSScriptObjectSpecifier to that magazine, whose container is the application object (not the internal list the current magazine might be in). For example:

- (NSScriptObjectSpecifier *)objectSpecifier
{

  NSScriptClassDescription *containerClassDesc = (NSScriptClassDescription *)
      [NSScriptClassDescription classDescriptionForClass:[NSApp class]];

  return [[[NSNameSpecifier alloc]
      initWithContainerClassDescription:containerClassDesc
                     containerSpecifier:nil 
                                    key:@"magazine"
                                   name:self.name]];
}

When accessed in AppleScript, you should then see, for example,

tell application "My Magazines" to get current magazine
--> magazine "New York Times" of application "My Magazines"
Ron Reuter
  • 1,287
  • 1
  • 8
  • 14
0

I had this same problem.

When I asked Script Editor for page 1 of my document 1 it came back with:

«class » 1 of «class » 1 of application "My App"

but:

class of page 1 of document 1

returned

page

as expected.

the solution

I'd based my .sdef on Based /System/Library/ScriptingDefinitions/CocoaStandard.sdef, adding my own suite.

but when I checked my .sdef I saw that I had inherited my document from the standard document. I should have used class-extension in my suite in my sdef file.

actual code:

  <suite name="SimpleComic Suite" code="Acmx"
          description="SimpleComic specific classes.">
        <class-extension name="document" code="docu" description="A document." extends="document">
            <cocoa class="TSSTSessionWindowController"/>
            <element type="page"/>
      <property name="current page" code="ppag" type="integer" description="The document's current page number." >
                <cocoa key="pageSelectionIndex"/>
            </property>
    </class-extension>
    <class name="page" code="cpag" description="A page.">
            <cocoa class="TSSTPage"/>
    </class>
  </suite>

See Also:

https://keith.github.io/xcode-man-pages/sdef.5.html#class-extension

How to support an AppleScript element (a one-to-many relation) of the application (NSApp) class?

DavidPhillipOster
  • 4,195
  • 1
  • 19
  • 17