为什么我的 macOS 应用程序在实施 AppleScript 支持后停止响应默认的 AppleScript 命令?

Why does my macOS application stop responding to default AppleScript commands when AppleScript support is implemented?

我正在尝试在我为 macOS 编写的应用程序中实现 AppleScript 支持(或者,更准确地说,更新 - 这是一个 Objective C 应用程序)。 sdef文件如下:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE dictionary SYSTEM "file://localhost/System/Library/DTDs/sdef.dtd">
<dictionary title="FileDump">
    <suite name="FileDump Suite" code="FLDS" description="File Dump Scripts">
        <command name="List" code="lflecont" description="List file types found in data stream">
            <cocoa class="ListDataContentCommand"/>
            <result type="any" description="an array containing the types of all the data blocks in the File"/>
        </command>
        <command name="Get" code="gflecont" description="Get contents of Data Object">
            <cocoa class="GetFLEItemCommand"/>
            <direct-parameter type="text" description="The Data Object to get"/>
            <result type="any" description="a data object containing the requested item"/>
        </command>
    </suite>
</dictionary>

我已经按照 this answer 中的描述更新了 info.plist。

如果我将 NSAppleScriptEnabled 设置为 false,那么脚本编辑器会说我的应用程序不可编写脚本(如您所料),但我的应用程序会响应标准套件(例如打开文档)。

如果我将 NSAppleScriptEnabled 设置为 true,那么脚本编辑器会正确显示我的应用程序的字典,但我的应用程序不再响应标准套件 - 尝试打开文档超时。

我的应用程序是基于 NSDocument 的。我究竟做错了什么?如何使我的应用程序可编写脚本并让它响应标准套件?

如果您没有为您的应用程序启用 AppleScript,系统将自动为四个主要命令提供基本的 AppleScript 支持:openquitprint 和另一个我可以手头记得。

如果您启用 AppleScript,系统假定您将在 SDEF 文件中提供所有支持的命令。如果您不为这些基本命令提供 XML,它们将不可用。添加标准命令有两种典型的方式:


如果您只想支持其中的几个命令,可以将系统文件“CocoaStandard.sdef”的相关部分复制到您自己的sdef文件中。在以下位置找到该文件:

/System/Library/ScriptingDefinitions/CocoaStandard.sdef

确保复制完整的 XML 块,并且它们包含在给定的“标准套件”套件块中。您可以随意修改这些命令,只要您不这样做更改 code 属性中的 4 字符和 8 字符代码。系统使用这些代码来识别标准命令。


如果要包含所有标准命令,可以使用 xinclude。更改开头的 Dictionary 标签以启用 xinclude(如图所示添加 xmlns:xi 属性),然后添加一个 xi:include 标签以从系统中拉入标准套件命令:

<dictionary xmlns:xi="http://www.w3.org/2003/XInclude">
    <xi:include href="file:///System/Library/ScriptingDefinitions/CocoaStandard.sdef" xpointer="xpointer(/dictionary/suite)"/>

您不能通过这种方式修改或删除任何标准命令,但可以节省时间和精力。


openreopenquit(也许)print 应该可以在没有任何特殊代码的情况下工作,但如果你想要应用程序,你可能必须重写 NSApplicationDelegate 方法-特定行为。其他标准套件命令将需要以各种不同的方式实现,否则您将收到 'Apple Event Handler Failed' 错误消息。有关详细信息,请参阅 this section of the Cocoa Scripting Guide