10.6 Changes

This article describes changes to AppleScript and related tools in Mac OS X Snow Leopard v10.6.

Tool Reorganization

In order to streamline the /Applications folder, the /Applications/AppleScript folder has been removed, and its contents reorganized:

AppleScript Editor

AppleScript Editor has several significant enhancements:

AppleScript Editor is now more responsive while running a script, and can run several scripts simultaneously. Previous versions would let you start running a second script, but the first one would pause until the second one finished. It does this by running scripts on background threads. If this causes trouble, typically because a third-party scripting addition has claimed to be thread-safe but isn’t, you can force the script to run on the main thread by holding the Control key and selecting the Run command, which will show as “Run in Foreground” in the menu.

Syntax coloring for scripts now has much more detail: commands, parameters, classes, properties, and enumerated values all have their own category now, instead of sharing the “application keywords” category, and may be formatted differently depending on whether they come from an application or a scripting addition. This allows scripters to better determine what a term is simply by looking at the compiled script.

The Result and Event Log panes have been merged into a single pane with three visibility controls: Result, Events, and Replies. Selecting “Result” shows only the script result, much like the old Result pane. Selecting “Events” or “Replies” shows Apple events sent by the script and the values returned by the events, respectively, along with the output from any explicit log commands, and the final result at the end. These controls are dynamic: you may change them at any time, even while the script is running, and the appropriate bits of the log will be hidden or shown. Hovering over an event in the log will show a tooltip with the raw Apple event contents, including all the four-byte codes.

There is now an option to enable a new Tell Application pop-up in the navigation bar: this controls the default target of the script, effectively putting a tell block around the entire script. This is useful for exploring an application’s scriptability, since there is then no need for an explicit tell, or for testing scripts that will eventually be run inside another application: for example, when writing a Mail rule script, you would set the default target to Mail. This setting is saved with the script, but does not affect the script’s behavior if it is saved as an application: the default target is still that application. You can enable this feature in AppleScript Editor’s “Editing” preferences. The applications in the pop-up are controlled by the contents of the Library window.

Scripting Addition Security

For security reasons, most scripting addition commands now return a “privilege violation” error when sent between application processes. In order to preserve compatibility with existing scripts, AppleScript redirects most of these commands to the current application, that is, the process running the script. If a script sends events to a remote computer via EPPC (“Remote Apple Events”), AppleScript may redirect them to the System Events process on the target machine. AppleScript Editor’s Event Log will show when this redirection happens: you will see the event sent first to the original target process, return an error, and then sent again, often to the current application.

Some scripting addition commands, such as display dialog, must be handled within the target process to operate correctly, and may require authenticating as an administrator if any of the following are true:

If the event can be successfully redirected to the current process, then it didn’t need to be sent to the target process in the first place. You can eliminate the unnecessary double-send by moving the scripting addition command outside of the tell block, or by adding tell current application to to the command. For example, this script makes a new folder on the desktop named with the current date, but does it in a way that requires current date to be sent twice:

tell application "Finder"
    set folderName to date string of (current date)
    make new folder with properties {name:folderName}
end tell

To eliminate the double send, move the current date outside of the tell block:

set folderName to date string of (current date)
tell application "Finder"
    make new folder with properties {name:folderName}
end tell

Or add an inner tell applying to the addition command:

tell application "Finder"
    tell current application to set folderName to date string of (current date)
    make new folder with properties {name:folderName}
end tell

Other Enhancements

AppleScript

When getting the text items of a string, all the values in text item delimiters are considered. Previous versions only considered the first item in the list. [1186965]

AppleScript itself no longer depends on being run within a login session, and may be run from outside the current user’s login, such as via an ssh(1) session or in a root cron(8) job. However, external code that a script uses, such as scripting additions or applications, may still require a login session. [3192824]

The various types of ignoring behavior for text comparisons are now defined using Unicode General Categories, not ASCII characters:

  • ignoring punctuation ignores category P*: for example, left- and right-quotation marks are now ignored. However, the backtick character (`) used to be ignored but is now considered, because Unicode classifies it as a symbol, not punctuation.

  • ignoring hyphens ignores category Pd: for example, em- and en-dashes are now ignored.

  • ignoring whitespace ignores category Z*, plus tab (\t), return (\r), and linefeed (\n): for example, non-breaking spaces are now ignored.

For further details on General Categories, see the Unicode Standard, section 4.5. [4819817]

Standard Additions

If a do shell script command exits because of a signal, including a crash, do shell script will throw an error. The error number will be the signal number plus 1000, to allow distinguishing signal errors from exit status errors, which are always 255 or less. Formerly, the signal was ignored.

say now has several optional parameters for customizing voice parameters: speaking rate, pitch, modulation, and volume, and asynchronous speech no longer requires the Speech status window to be open. See the Standard Additions dictionary for more details.

Command Line

osascript now supports the log command; the output will be sent to stderr. [6260159]

Folder Actions

Folder Actions now supports attaching an Automator workflow as a folder action. Only “files added” actions are supported; the added files will be the input to the workflow.

Bug Fixes

AppleScript

Performance of getting elements of text has been improved. [2206026]

The startup time of the AppleScript interpreter has been improved. [3188110].

character elements are counted the same way offset of counts them, so character counts now always match between the two. [5578622]

In general, AppleScript in 10.5 and later will consider the class constants string and text equal. However, this did not apply to list containment, so class of "foo" is in {string} would incorrectly return false. It now evaluates to true. [5581947]

If a script uses using terms from blocks, the targets will not trigger a “Where is…” dialog when the script is run on 10.4 and earlier systems. [5823283]

AppleScript Editor

“Undo” now works correctly across Compile commands.

Folder Actions

Folder Actions now attempts to delay calling “files added” actions on files until they are done being copied. Previous versions called “files added” actions on new files as soon as they appeared in the file system. This was a problem for files that were being copied into place: if the file was sufficiently large or coming over a slow server link, the file might appear several seconds before it was done being copied, and running the folder action before it finished copying would behave badly. Folder Actions now watches if the file is changing size: if it stays the same size for more than three seconds, it is deemed “done”, and the action is called.

Compatibility Notes

64-bit

AppleScript Editor and osascript(1) run in 64-bit mode by default on hardware that supports it. This can be an issue for scripting additions: Standard Additions is fully 64-bit capable, but third-party additions may not be, and will refuse to load with a console message such as this:

Error loading Potrzebie.osax/Contents/MacOS/Potrzebie:
  dlopen(Potrzebie.osax/Contents/MacOS/Potrzebie, 262): no suitable image found.
Did find:
  Potrzebie.osax/Contents/MacOS/Potrzebie: mach-o, but wrong architecture

This only affects scripts that rely on commands in that scripting addition; otherwise the message is effectively a warning. If a 64-bit version of the addition is not available, you can work around the issue by forcing the process running the script to run in 32-bit mode, either by using the “Open in 32-bit mode” option in Finder’s “Get Info” panel, or by using arch(1), such as this:

arch -i386 osascript 32-bit-only.scpt

Script File Formats

AppleScript Editor no longer supports saving applications in the old single-file format. All scripts saved as an “Application” will be saved as an application bundle with three supported architectures: ppc, i386, and x86_64. Such applications can run on Mac OS X v10.3 and later. Old single-file applications opened in AppleScript Editor will be treated as read-only files: you must use Save As to save them, and they will be saved in the new format.

osacompile now outputs data-fork scripts by default. This matches AppleScript Editor. To create a resource-fork script compatible with classic Mac OS, use the option -r scpt:128. [6325665]

Dates and Times

Parsing of date strings now uses CFDateFormatterCreateDateFromString, which means that custom date formats, Unicode-only locales such as Arabic, and non-Gregorian calendars are now all handled correctly. However, it is also much more restrictive about deviating from the system date format. Previous versions would accept anything that looked even vaguely like a date: the string could omit components, reorder others, add or omit punctuation, and so on. In AppleScript 2.1, the string must exactly match one of the system date formats (full, long, medium, or short; see System Preferences > International > Formats for examples), including all punctuation and whitespace. The only difference allowed is to use either a two- or four-digit year, regardless of what the format uses.

Some scripts used partial date specifiers as a way to get dates relative to the current date, such as date "1/31" for January 31 of the current year, or date "15" to get the 15th of the current month. To do this in AppleScript 2.1, get a base date and then set the desired components using the properties of the date object. For example, to get January 31 of the current year:

set d to date "1/31/2000"
set year of d to year of (current date)
d --> date "Saturday, January 31, 2009 12:00:00 AM"

Alternatively, start with current date as the base. To get the 15th of the current month:

set d to current date
set day of d to 15
set time of d to 0
d --> date "Friday, May 15, 2009 12:00:00 AM"

This technique works with all versions of AppleScript, and can be used for scripts that must run on 10.6 and 10.5 and earlier.

Text

character elements are now counted using CFStringGetRangeOfComposedCharactersAtIndex. This mostly matches the 10.5 behavior of counting grapheme clusters, but counts a CR-LF (\r\n) sequence as two separate characters, as it did in 10.4 and earlier, not one.

word elements are now counted using kCFStringTokenizerUnitWordBoundary, which produces better results for non-Roman languages, and matches the definition of a “word” in the rest of the system, such as when double-clicking in text. As noted in AppleScript Language Guide, the word-break rules may change depending on user settings and system software updates, and should not be relied upon for deterministic parsing of text.

As described in Other Enhancements, ignoring categories now ignore relevant characters in the entire Unicode character set, not just ASCII. The results of comparisons are more correct, but may differ from previous versions.

Apple Events

ssh(1) sessions are now in the same security space as other processes owned by the same user, and therefore send Apple events to each other. This means that a user can now use ssh(1) to run a script and control applications on a remote machine if they are also logged in as the console user on that machine.

Mac OS X v10.6 no longer supports sending remote Apple events to Mac OS 9 machines.

Developer Notes

64-bit

AppleScript, Standard Additions, and all AppleScript-related system applications such as System Events are fully 64-bit capable. Scripting addition developers should make their additions 64-bit-capable as soon as possible, otherwise they will not work on 64-bit systems without extra steps by the user. (See Compatibility Notes.) 64-bit-capable scripting additions should use the updated format for Mac OS X v10.6; see TN1164, Scripting Additions for Mac OS X, for details.

Thread Safety

OSA and AppleScript are now thread-safe: they may be safely called on a non-main thread or from multiple threads without any locking in the client code. This also applies to NSAppleScript. This does not mean that AppleScript is totally concurrent: AppleScript uses locking to ensure that any single connection (a ComponentInstance) will only run on one thread at a time. Because of the size of the locking granularity, trying to manipulate the same script from multiple threads at once may still be subject to race conditions, and is not recommended.

Before using a scripting component on a background thread, developers should test the component’s “thread-safe” bit (cmpThreadSafe in the ComponentDescription’s componentFlags.) Test the generic component before using OSA on a background thread, and then test the specific language component before using it on a background thread.

Scripting Additions and Thread Safety

Since a scripting addition can contain arbitrary code, a given addition command may or may not be thread-safe: offset of is, for example, but display dialog is not. For compatibility, addition commands are presumed to be thread-unsafe, and will be executed on the main thread. Commands may be marked as thread-safe using an expanded Info.plist definition; see TN1164, Scripting Additions for Mac OS X, for details. Coercion handlers in scripting additions must be thread-safe; again, see TN1164 for details. Scripting addition developers should review and, if necessary, update their additions for thread-safety.

AppleScript Identifiers

AppleScript now uses different rules for capitalizing identifiers accessed through the OSA APIs. These changes are intended to preserve capitalization information and make it unnecessary to know internal rules of AppleScript. When accessing a property or handler, such as by using OSAGetProperty or OSAExecuteEvent with a “call subroutine” event, the identifier is handled case-insensitively. Formerly, you had to lowercase the identifier before passing it to AppleScript. When getting a property or handler name, such as by using OSAGetPropertyNames or when a script result contains a user identifier, the identifier will be capitalized as it was in the script, which may be mixed-case. Formerly, identifiers would always come out all-lowercase.

Scripting Definitions (sdefs)

OSACopyScriptingDefinition now has a sister function OSACopyScriptingDefinitionFromURL, which can accept either a file: or eppc: URL.

OSACopyScriptingDefinition now does a better job preserving information in hidden aete suites.

10.6.2 Changes

AppleScript Editor will now open certain malformed application dictionaries.