Cocoa脚本:从“重复”命令

时间:2016-05-15 14:11:32

标签: applescript cocoa-scripting

AppleScript duplicate命令应该返回复制的对象。

虽然使用原始基于AE的功能的应用程序似乎这样做,但基于Cocoa Scripting框架的应用似乎永远不会返回任何东西,但缺少值

NSCloneCommand的命令处理程序似乎负责不返回克隆对象的说明符。

我试图通过继承命令,收集克隆的对象说明符然后返回它们来在我的脚本化应用程序中解决这个问题。

如果只复制一个项目,则效果很好。

如果在命令中使用to参数克隆多个项目(如在duplicate every widget to end中),它也可以工作:然后我可以返回一个类型为NSRangeSpecifier的指定符,用于指定第一个和最后一个克隆项目。

但是,如果在不使用 to参数的多个项上使用重复命令,则项目将在中排序到数组中非连续的方式。例如,如果最初有2个“x”元素,id为1,则duplicate every x将在其原始元素之后插入每个元素的副本,以便我们按此顺序排列它们:1,3 ,2,4。

现在,如何为此返回一个说明符,即第3项和第4项的说明符?

NSScriptObjectSpecifier的子类中没有“list”说明符,似乎也不能为每个NSScriptObjectSpecifier返回NSArray。虽然NSAppleEventDescriptor支持创建列表,但我无法弄清楚如何将对象说明符转换为NSAppleEventDescriptors。

除了强制执行克隆对象的连续顺序之外,我怎么能解决这个问题(这需要我完全重新执行NSCloneCommand的操作,我担心。)

BTW,Mark Aldritt,脚本调试器的作者,confirms the issueduplicate(同时:moveopen)不返回值,因为它们是应该。

2 个答案:

答案 0 :(得分:1)

Mark Aldritt对我有所帮助,告诉我一些私有API方法:

@interface NSScriptObjectSpecifier (NSPrivate)
+ (id) _scriptingSpecifierWithDescriptor:(NSAppleEventDescriptor*) descriptor;
+ (id) _objectSpecifierFromDescriptor:(NSAppleEventDescriptor*) descriptor inCommandConstructionContext:(id) context;
- (NSAppleEventDescriptor*) _asDescriptor;
@end

我正在寻找_asDescriptor - 一种将对象说明符转换为NSAppleEventDescriptor的方法,以便我可以将它添加到列表对象中。代码看起来像这样:

- (NSAppleEventDescriptor*) objectSpecifiersAsList:(NSArray*) objectSpecifiers {
    NSAppleEventDescriptor* result = [NSAppleEventDescriptor listDescriptor];
    for (NSScriptObjectSpecifier* specifier in objectSpecifiersArray) {
        [result insertDescriptor:specifier._asDescriptor atIndex:0];
    }
    return  result;
}

当我尝试返回非连续项时,我发现这不起作用。实际上,它与返回相同NSArray的{​​{1}}具有相同的效果。这是一个例子:

NSScriptObjectSpecifier

使用自定义复制命令处理程序返回复制的项目3和4的说明符列表,AppleScript最终再次调用相同的命令处理程序,然后它给出错误-10006并显示以下消息:

set x to duplicate widgets 1 thru 2

请注意 - 它没有说“小部件3到4”或“{小部件3,小部件4}”。不,它总是将第一个参数给出的项目报告给重复命令。

只要我将代码更改为返回单个说明符或范围说明符,该命令就会再次正常运行。

所以看起来这是Cocoa Scripting(或AppleScript?)中隐藏的错误,它无法处理列表中的返回对象说明符。

更新&溶液

经过更多的反复试验后,我发现了一种有效的方法:

结果的类型必须从“描述符”改变,有两种可能性:

  • 要使用返回Can't set widgets 1 thru 2 to widgets 1 thru 2 的上述代码,结果类型必须为“any”,即:

    listDescriptor
  • 或者,如果结果类型更改为“任何列表”,则可以返回包含<result> <type type="any"/> </result> 值的NSArray:

    NSAppleEventDescriptor

但是,两种解决方案都需要使用私有<result> <type type="any" list="yes"/> </result> 方法,因为没有其他已知方法可将脚本化对象转换为_asDescriptor

(当然,如果您的应用仅支持一种类型的元素的NSAppleEventDescriptor命令,那么您可以将类型更改为“yourtype列表”并简单地返回对象的NSArray,而无需私有方法 - 只返回类型为duplicate的结果时才需要。)

Mark说这是关于使用私有方法:

  

如果您担心Mac App Store问题,Apple会向我提供这些私有方法,因为没有替代API。我很确定你可以获得使用它们的许可。

我希望尽快将我自己的应用程序提交到App Store。然后,我将使用私有函数的结果更新此答案。

答案 1 :(得分:0)

托马斯,我不确定这是不是一个错字,但我没有看到标准套件中重复命令的“at”参数:

<command name="duplicate" code="coreclon" description="Copy an object.">
    <cocoa class="NSCloneCommand"/>
    <direct-parameter type="specifier" .../>
    <parameter name="to" ...</parameter>
    <parameter name="with properties" ...</parameter>
</command>

也没有<result ...>元素,因此根据定义,命令不应返回任何值或值。我错过了什么吗?