0

I'm trying to implement AppleScript support in an Application that I'm writing for macOS (or, more accurately, updating - It's an Objective C application). The sdef file is as follows:

<?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>

I've updated the info.plist as described in this answer.

If I set NSAppleScriptEnabled to false then Script Editor says that my application isn't scriptable (as you'd expect), but my application responds to the standard suite (open document, for example).

If I set NSAppleScriptEnabled to true then Script Editor shows the dictionary for my application correctly, but my application no longer responds to the standard suite - trying to open a document times out.

My application is NSDocument based. What am I doing wrong? How can I make my application scriptable and have it respond to the standard suite as well?

headbanger
  • 1,038
  • 1
  • 11
  • 32
  • There are many things which can go wrong. And each single one breaks the entire functionality. Do you get errors? Commands can be Verb-first or Object-first. – vadian Mar 21 '21 at 19:10
  • It times out (Appleevent timed out) if NSAppleScriptEnabled is turned on. It runs normally (and quickly <1 sec) if NSAppleScriptEnabled is turned off. – headbanger Mar 21 '21 at 20:59

1 Answers1

3

If you do not enable AppleScript for your app, the system will automatically provide basic AppleScript support for four primary commands: open, quit, print and one other I can't remember off hand.

If you do enable AppleScript, the system assumes that you will provide all supported commands in your SDEF file. If you don't provide XML for those basic commands they will not be available. There are two typical ways of adding standard commands:


If you only want a few of the commands to be supported, you can copy the relevant parts of the system file "CocoaStandard.sdef" into your own sdef file. Find that file at:

/System/Library/ScriptingDefinitions/CocoaStandard.sdef

Make sure that you copy over full XML blocks, and that they are contained within the given 'Standard Suite" suite block. You can modify these commands as you like, so long as you don't change the 4-char and 8-char codes in the code attribute. The system uses those to identify the standard commands.


If you want to include all of the standard commands, you can use xinclude. Change the opening Dictionary tag to enable xinclude (adding the xmlns:xi attribute as shown), and then add an xi:include tag to pull in the standard suite commands from the system:

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

You cannot modify or remove any of the standard commands this way, but it can save time and effort.


open, reopen, quit (and maybe) print should work without any special code, though you may have to override NSApplicationDelegate methods if you want app-specific behaviors. Other standard suite commands will need to be implemented in various different ways, or you'll get 'Apple Event Handler Failed' error messages. See this section of the Cocoa Scripting Guide for more info.

Ted Wrigley
  • 2,921
  • 2
  • 7
  • 17