Creating an AppleScript bundle on MacOS

— The language of Automation —

How it works in theory

Suppose you write some AppleScript that is generic and that you would like to use in other AppleScript applications. The solution is to create a library from it and store it in a standard place where your other AppleScript applications can find them.

MacOS has a standard place where you can store libraries. This central place is typically, but not limited to ~/Library/Script Libraries/. Note that you may have to create this folder if it doesn’t exist.

Then, there are two options that you have:

  1. Compile the script and store it in the standard place
  2. Create a bundle that contains the compiled script and is stored in a central place

The main difference between the two options is that a bundle allows, beside the code, a dictionary that you can view and use to provide your code with proper documentation.

An sctpd bundle is a compiled AppleScript script that forms a library to be used by other scripts.

From an high level view a sctpd bundle is a directory with the suffix sctpd and in there there are 3 files that are the basis of the bundle.

  1. The compiled AppleScript code, and it has the mandatory name main.scpt.
  2. A scripting definition file that provides that syntax and documentation to the users of the library. The file is named Package.sdef where Package matches the name of your library.
  3. The file Info.plist which provides metadata for the Package.

An example of a package named “Regular Expressions” is as follows:

In order to show the different steps, we will create the library in 3 steps:

  1. Create an application. The application will have some methods that will be used to create the library.
  2. Create a compiled library that contains the code from the application.
  3. Create a bundle that contains the compiled library and the dictionary.

Creating an application

The first step is to create an application that contains the code that will be used to create the library.

The code for the application is as follows:

This application is kept extremely simple. It contains three methods named four, square and mult.

Assuming that the application is stored as application.applescript the application can now
Be run using the following command from the terminal:


	osascript application.applescript

The methods are called and the results are printed to the console.

	4
	16
	15

This example is kept simple on purpose to show the basic steps of building a library and not on producing a useful library.

Creating a compiled library

To create a compiled library you need the application needs to be split into two parts. The first part is the code for the library and the second part is the application that uses the library.

The
code
For the library is as follows:

You can use the Script Editor application to create this file. When you save the file, make sure to select the File Format as text.

Using text format uses plain ASCII to save the file. This is a personal preference, but I prefer to use text format because it is easier to read and edit the file in a text editor.

Assuming this file was saved as match.applescript, you can compile it using the following command in the terminal:


  osacompile -o ~/Library/Script\ Libraries/math.scpt math.applescript

This command will create a compiled library in the ~/Library/Script Libraries/ folder. The name of the file is math.scpt.
The math.scpt file is a compiled version of the math.applescript file.

To use our created in an AppleScript application, you need to create a script that uses the library.

  1. By using a tell statement:

  2. By using a use script statement:

  3. By using a property statement:

Assuming the application is saved as
application.applescript the application can be run using the following command in the terminal:

  
  osascript application.applescript
  

Creating a bundle

Creating the bundle can be done using the application Script Editor.

Create the basis

Create a new script and then immediately save it. You will be prompted to provide the file name and the location. It is import to change the default File Format to Script Bundle

Add the code

Enter the code of the library and push the indicated button:

It will show the following window:

Where:

  1. This is the name of the library.
  2. This is the identifier of the library. Currently it has an identifier in the apple domain but you could change this to match your own domain.
  3. The version number. You can change this as needed.
  4. The bundle version. This is typically not changed.
  5. A copyright notice you see fit
  6. The Scripting Definition File. More to follow on this field
  7. Please note that although the Scripts seems empty it is not. It does contain the compiled script named main.scpt

The next step is to add the Scripting Definition File

The Scripting Definition File, i.e. the Sdef file

The Scripting Definition File is an XML file. In public domain there is an editor that you can use. The original is on GitHub here. This application has not been updated for a long while and an updated version can be found on Late Night Software here.

For the purpose of explaining the process, I’m going to create the file by hand and explain the culprits that you have to look out for.

First there is the basis:

The next step is to add the suite definition to the file:

Please note that the code of the suite MUST have 4 characters, typically all upper case. The name field
Defines under what name you categorize the commands (see later).

You can have multiple suits, for example one for “Math” and one for “Text”. By putting the commands in the appropriate section it becomes easier to find the appropriate command.

The next step is to define the first command:

Please note that the code of the command MUST have 8 characters. It is convention to use the given syntax where the first part somehow resembles the suite and the latter part the command. A colon is not required.

Then the result of the method needs to be defined:

The method is returning an integer.

Finally, last but not least, we must document our impressive method:

Please note that:

  1. The html label is optional. You can document the method with plain text as well.
  2. The documentation can include all kind of formatting code. In this case the highlight JS
    code is inserted. This will support nice coloring of the code sections.

  3. The actual documentation

For readability the documentation will be left out in the remainder of this article.

This concludes the first command. Next the square command needs to be added.

The main difference between four and square is that square accepts an argument. This argument is added, including the type of the argument.

Then finally our last method mult will be added:

Please note that additional parameters are added using a parameter tag and that
the code MUST have a 4 character code.

This concludes the definition of the file. Next step is to install the file into the bundle.

Drag the Sdef file into the Script Editor side pane. Then enter the name math
in the Scripting Definition field.

Installing the bundle

In the terminal type the following command:


  cp -r math.scptd ~/Library/Script\ Libraries/

This will copy the bundle to the ~/Library/Script Libraries/ folder.

In case you installed the compiled version of the library before, remove that compiled version:


  rm -f ~/Library/Script\ Libraries/math.scpt

This will remove the previous installed compiled version.

Using the bundle

Now that the bundle has been installed, you can open the dictionary of the new library.

In Script Editor under File, use Open Dictionary…
and select the match entry. You will get something like this:

You would expect that the bundle can be used in the same way as the compiled library:

  1. This works:

  2. This doesn’t work:

  3. And this also doesn’t work:

So it looks like beside having a dictionary with documentation, you gained nothing and lost a lot.

This is partially true. However we could add some more code to make the contents of our match library
accessible without the construct “math’s“.

Add the following code to the definition of the math library:

This may look weird initially. Let’s explain the red boxes. This is referring to the code that you defined in the Sdef, XML:

As you can see the command code is used for the event identifier and the code from the parameter is used as the identifier of the class.

Then there are these weird characters around event and class. These are called
LEFT-POINTING DOUBLE ANGLE QUOTATION MARK and RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK.

You can enter those using the Character Viewer. To open the Character Viewer use the keyboard command: Control-Command-Space bar:

Please remember if you edited the original you may have to copy it again:


  cp -r math.scptd ~/Library/Script\ Libraries/

Next edit the application and add the following construct:

This shows that you have to choose the names of the arguments carefully to form understandable sentences.

Gotchas

  • The Script Editor caches the dictionaries (libraries). Which means that if you had your editor open whilst you were copying the new dictionary into place, it will not be seen.

    You have to quit the Script Editor and open it again to clear this cache.

  • If you make a mistake the errors can be confusing to say the least. My advise is to make small steps and compile frequently.

    For example:

    This example has made the mistake that the variable that is being assigned on line 5 has the name ‘text’ which is a known type by AppleScript. The error seems to be inside the use line.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.