2

I want to make my app scriptable and am running into a few issues I hope some of you may help me with since my experience with making apps scriptable is not great.

The app is not document-based and has a several global named objects of the same class that I want to be accessed from AppleScript. For example, say that I want to have a several catalogues, each named, say "animals", "plants", "cars". I have managed to add several properties to the application class (in AppleScript), each representing one of the catalogues:

<class name="application" description="My application." code="capp" inherits="application">
  <cocoa class="NSApplication"/>
  <property name="animals catalogue" code="acat" description="…" type="catalogue" access="r">
    <cocoa key="animalsCatalogue"/>
  </property>
  <property name="cars catalogue" code="ccat" description="…" type="catalogue" access="r">
    <cocoa key="carsCatalogue"/>
  </property>
  <property name="plants catalogue" code="pcat" description="…" type="catalogue" access="r">
    <cocoa key="plantsCatalogue"/>
  </property>
</class>

I am able to successfully fetch any of those variables, e.g.

tell application "MyApp"
  set c to get animals catalogue
end tell

gets me really the catalogue variable («class ����» "Animals" of application "MyApp").

Unfortunately, where it gets tricky is when it comes to getting a property from the catalogue - for example 'empty'. Here is the catalogue definition:

<class name="catalogue" code="ctlg" description="...">
    <cocoa class="XYCatalogue"/>
    <property name="empty" code="empt" description="Is the catalogue empty?" type="boolean" access="r">
        <cocoa key="isEmpty"/>
    </property>
</class>

The issue here is that when running this AppleScript:

tell application "MyApp"
  set c to get animals catalogue
  get empty of c
end tell

results in an error: MyApp got an error: Can’t make «class ����» "Animals" into type specifier.

Implementation-wise, I have the NSApplication subclassed (and yes, I have specified the main class in Info.plist), which implements several methods, returning those particular catalogues. The XYCatalogue class implements the -objectSpecifier method this way:

return [[[NSNameSpecifier alloc] initWithContainerClassDescription:
                  [NSScriptClassDescription classDescriptionForClass:[NSApp class]]
                               containerSpecifier:nil 
                               key:@"allCatalogues" 
                               name:[self name]] autorelease];

The NSApplication subclass implements a -allCatalogues method that returns all the catalogues. I have tried even using the NSUniqueIDSpecifier and the NSPropertySpecifier, all in vain. And yes, the NSApplication subclass does implement both -valueWithName:inPropertyWithKey: and -valueInAllCataloguesWithName: methods and neither is invoked (have breakpoints in both of them).

I have sincerely read Apple's guide several times, however, still can't figure out where is the issue and I'm hanging on this for a few days now. I would be most thankful for any nudge in the right direction. Thanks!

4

1 回答 1

2

您没有看到正确的类名(例如动物目录)而是看到«class»代码这一事实很好地表明您的-objectSpecifier函数返回了错误的说明符。

有一个重要的规则需要遵循-objectSpecifier

传递给的键-initWithContainerClassDescription:必须与为该类在 下的属性定义输入的键相同<cocoa key>。但是,在您的示例中,它们不匹配:属性访问器称为animalsCatalogue但您使用的键-objectSpecifierallCatalogues。他们需要匹配。

此外,正如 Apple 文档所说,这containerSpecifier可能仅适用nil于目标是应用程序,而不适用于任何其他可编写脚本的对象。如果您为非应用程序对象传递 nil,Cocoa 脚本引擎可能不会将此作为错误报告回来,但结果将类似于传递错误的键。

于 2016-04-01T12:09:03.083 回答