Search code examples
objective-ccocoaapplescript

AppleScript class name displayed in AppleScript Editor


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];

}


Solution

  • 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"