Mark Aldritt进一步帮助了我,告诉我一些私有 API 方法:
@interface NSScriptObjectSpecifier (NSPrivate)
+ (id) _scriptingSpecifierWithDescriptor:(NSAppleEventDescriptor*) descriptor;
+ (id) _objectSpecifierFromDescriptor:(NSAppleEventDescriptor*) descriptor inCommandConstructionContext:(id) context;
- (NSAppleEventDescriptor*) _asDescriptor;
@end
这_asDescriptor
是我一直在寻找的 - 一种将对象说明符转换为 a 的方法,NSAppleEventDescriptor
以便我可以将其添加到列表对象中。代码如下所示:
- (NSAppleEventDescriptor*) objectSpecifiersAsList:(NSArray*) objectSpecifiers {
NSAppleEventDescriptor* result = [NSAppleEventDescriptor listDescriptor];
for (NSScriptObjectSpecifier* specifier in objectSpecifiersArray) {
[result insertDescriptor:specifier._asDescriptor atIndex:0];
}
return result;
}
但是,当我尝试使用此方法返回非连续项目时,我发现这不起作用。实际上,它与返回NSArray
相同NSScriptObjectSpecifier
s的an具有相同的效果。这是一个例子:
set x to duplicate widgets 1 thru 2
使用自定义重复命令处理程序返回复制项 3 和 4 的说明符列表,AppleScript 最终会第二次调用相同的命令处理程序,然后它给出错误 -10006 并显示以下消息:
Can't set widgets 1 thru 2 to widgets 1 thru 2
请注意 - 它没有说“widgets 3 thru 4”或“{widget 3, widget 4}”。不,它总是将第一个参数中给出的项目报告给重复命令。
一旦我将代码更改为返回单个说明符或范围说明符,该命令就会再次正常运行。
因此,这似乎是 Cocoa 脚本(或 AppleScript?)中的一个隐藏错误,它无法处理列表中返回的对象说明符。
更新与解决方案
经过更多的反复试验,我找到了一种可行的方法:
结果的类型必须从“描述符”更改,有两种可能:
要使用上面返回 a 的代码listDescriptor
,结果类型必须是“any”,即:
<result>
<type type="any"/>
</result>
或者,如果结果类型更改为“任何列表”,则可以返回包含NSAppleEventDescriptor
值的 NSArray:
<result>
<type type="any" list="yes"/>
</result>
然而,这两种解决方案都需要使用私有_asDescriptor
方法,因为没有其他已知方法可以将可编写脚本的对象转换为NSAppleEventDescriptor
.
(当然,如果您的应用程序duplicate
仅支持一种元素类型的命令,那么您可以将类型更改为“您的类型列表”并仅返回对象的 NSArray,而不需要私有方法 - 只需要返回类型的结果any
。)
马克说这个关于使用私有方法:
如果您担心 Mac App Store 问题,这些私有方法是 Apple 提供给我的,因为没有替代 API。我很确定您可以获得使用它们的许可。
我希望尽快将实现此解决方案的自己的应用程序提交到 App Store。然后,我将使用私有函数的结果更新这个答案。