AppleScript app development help

Got nothing when I tried other places, so I thought I’d try here, since I know there are developers intimate with AppleScript around here.

I’ve been adding AppleScript support to my app. Returning some objects to a script shows them as the wrong class. Like here’s the AppleEvent when I request “keyword 1 of document 1”:

<NSAppleEventDescriptor: 'core'\'getd'{ '----':'obj '{ 'form':'indx', 'want':'Keyw', 'seld':1, 'from':'obj '{ 'form':'indx', 'want':'docu', 'seld':1, 'from':null() } }, &'csig':65536 }>

Looks good. Now here’s the object specifier as seen in my app’s log when I have NSScriptingDebugLogLevel set to 1:

Result: <NSAppleEventDescriptor: 'obj '{ 'from':'obj '{ 'from':null(), 'want':'docu', 'form':'name', 'seld':'utxt'("_Untitled") }, 'want':', 'form':'name', 'seld':'utxt'(" test picts 2") }>

Notice the malformed value for the 2nd ‘want’. It should be ‘want’:‘Keyw’, but it’s ‘want’:’

Looking at the returned object in Script Debugger shows the same thing when I view as AEPrint:

'obj '{ 'form':'name', 'want':', 'seld':'utxt'(" test picts 2"), 'from':'obj '{ 'form':'name', 'want':'docu', 'seld':'utxt'("_Untitled"), 'from':[0x0,104003f "Image Chest"] } }

And viewed as Best shows:

asset "test picts 2" of document "_Untitled"

The class should be “keyword” not “asset”. Why is AppleScript being annoying? Here are the relevant hunks of code and sdef:

@implementation Keyword (NSScriptObjectSpecifiers)
-(NSScriptObjectSpecifier*) objectSpecifier
  Document* doc = self.doc;
  return [[NSNameSpecifier alloc] initWithContainerClassDescription:(NSScriptClassDescription*)doc.classDescription containerSpecifier:doc.objectSpecifier key:@"scriptableKeywords" name:self.scriptableName];
@interface Document
@property (readonly) NSArray<Asset*>* scriptableAssets;
@property (readonly) NSArray<Keyword*>* scriptableKeywords;
@property NSArray<Asset*>* scriptableSelection;
@interface Keyword
@property (readonly) NSString* scriptableName;

Relevant portion of .sdef:
<class name="asset" code="Asse" description="An asset being cataloged by the document.">
<cocoa class="Asset" />
<class-extension extends="document" description="A chest document.">
<cocoa class="Document" />
<property name="selection" code="sele" description="The selected assets.">
<cocoa key="scriptableSelection" />
<type type="asset" list="yes" />
<element type="asset" description="The assets being cataloged by the document.">
<cocoa key="scriptableAssets" />
<accessor style="index" />
<accessor style="id" />
<accessor style="test" />
<element type="keyword" description="The keywords known by the document.">
<cocoa key="scriptableKeywords" />
<accessor style="index" />
<accessor style="name" />
<accessor style="test" />
<class name="keyword" code="Keyw" description="A keyword used with assets.">
<cocoa class="Keyword" />
<property name="name" code="pnam">
<cocoa key="scriptableName" />
<type type="text" />

What’s that @property declaration doing in your keyword class definition?

Just looks like a forum editing mistake, possibly made when I went back and added the preformatted tags because most of my original post disappeared without them. I’ll fix it.

(Didn’t see this earlier because the forum prefs confused me and were set wrong - no email.)

I don’t see anything out of place, but then I rarely do just looking at sdefs. What happens if you change the codes for asset and keyword?

Tried changing both. No change. I looked for other dictionaries that have “keyword” and “asset” and only found “keyword parameter” in Script Debugger. I even tried changing the class names to “keywordXXX” and “assetXXX”. What part of AppleScript would be forming the returned descriptor to think the value for that ‘want’ is hosed?

Can you tell me if Script Debugger 7.0.8 is using a cached dictionary when clicking on an app in the Running section of the dictionary window and viewing the Explorer, or if it actually dives into the running app’s .sdef? If cached, how do I force it to load from the running app and not some other version of it (like in Applications)?

Go to Preferences -> Dictionary and uncheck Cache generated dictionaries. Hit Clear Cache as well if you’re feeling unlucky.

Having said that, AppleScript is generally much better with changing dictionaries these days.

You might also try this:

-(NSScriptObjectSpecifier*) objectSpecifier
  Document* doc = self.doc;
  NSScriptClassDescription* desc = [[NSScriptSuiteRegistry sharedScriptSuiteRegistry] classDescriptionWithAppleEventCode:cDocument];
  return [[NSNameSpecifier alloc] initWithContainerClassDescription:desc containerSpecifier:doc.objectSpecifier key:@"scriptableKeywords" name:self.scriptableName];

Hey, that did it! I mean changing how the doc’s class desc was formed when returning the Keyword obj spec. I don’t remember where I found the example for doing it the way I had it. It works for the Asset class. Should it work for any class, and why is your way working better?

Oh, doc.classDescription is returning nil. I’ll be dipped. That doesn’t seem right.

Arg. Asset is working because it’s doing:

	NSScriptObjectSpecifier*		objectSpecifier = doc.objectSpecifier;
	result = [[NSIndexSpecifier alloc] initWithContainerClassDescription:[objectSpecifier keyClassDescription] containerSpecifier:objectSpecifier key:@"scriptableAssets" index:idx];

You might also be able to use:

[NSScriptClassDescription classDescriptionForClass:[Document class]]

Is one of those better than the other?

I doubt it makes any difference, assuming they both work (I haven’t tried the latter). But the latter seems a bit easier to maintain more generally.

Thanks for the help, Shane.