Scripting in Swift: Scriptarian, take 1.2.1

Late last year, Scriptarian got quite a rough ride here. An attempt to produce a Swift-based substitute for AppleScript, at that time it looked promising in some respects, but had fragmentary support for AppleScript dictionaries, thus the AE Bridge, which is crucial to success.

Scriptarian has progressed over those eight months, AppleScript has continued to die slowly through neglect, and Apple yet again failed to announce or show any replacement at WWDC last month. This article catches up with what has been happening with Scriptarian, now at version 1.2.1.

Over that period, Scriptarian has stayed with Swift 3.0.1, although Xcode 8.3.3 now uses 3.1, and its next release (for High Sierra) supports 3.1 and 4.0. I don’t think that this is a big issue at present, but later this year as Xcode users are migrating to 4.0, it will be important for Scriptarian to adopt it.

The benefit, for the moment, is that it still accepts some elegant code such as theArray2 = Array(Set(theArray)) to eliminate duplicates from an array, which has become somewhat befuddled in Swift 3.1.


Language support is generally very good, and bundled documentation is excellent. For anyone not intimately familiar with Swift 3, Scriptarian’s approach is more accessible than Xcode’s documentation. For example, the entry for String is supplemented by separate entries for its nested types String.CharacterView, String.CharacterView.Index, and String.CharacterView.IndexDistance. This is almost as good as having a built-in copy of Dash, and based on common content.

Runtime support for macOS is still very patchy, and surprisingly limited in some areas. For example, Scriptarian’s interface to FileManager offers only six instance methods:

  • contentsOfDirectory,
  • fileExists,
  • directoryExists,
  • copyItem,
  • moveItem, and
  • removeItem,

each of which works with URLs not file paths.

Xcode 8.3.3 offers well over a dozen distinct functions, including createDirectory(), removeItem(), iCloud-based functions, support for symbolic and hard links, determination of access permissions, access to attributes, and more, and most of the more frequently-used calls are available to both URLs and paths. Without those functions, it is hard to see how a Scriptarian user might be able to perform many everyday file operations, a common task in scripting.

Scripting support has improved considerably, but still falls short of native AppleScript, and its documentation is contrastingly opaque. For example, Finder has a class Disk, a Finder.Container which represents a disk. Within that is an Instance Property format, which returns the format of that disk as Finder.Edfm, which is listed as a separate enumeration of different format types (which doesn’t yet include APFS). This fragmentary approach and lack of examples is not helpful to anyone, given that scripting AppleScript in Swift is a largely untrodden path.

One of the problems in Scriptarian’s approach to interfacing with AppleScript is that it relies on the app parsing and processing information from each app. As that can change over time, the few examples of scripting provided with Scriptarian need to be maintained. Of the six examples provided, one no longer appears to be supported by its app (Keynote) at all, and another (Safari) has apparently been broken by changes in the app’s AppleScript dictionary.

That said, this version of Scriptarian now provides useful and usable support for current releases of the following apps (and more): Calendar, Contacts, DatabaseEvents, Finder, Font Book, Grab, GraphicConverter, HelpViewer, ImageEvents, iTunes, Mail, MarsEdit, Messages, Microsoft Office (version 15), NisusWriterPro, Notes, Numbers, OmniGraffle, Pages, PCalc, Photos, RemoteDesktop, Safari, Skim, SystemEvents, SystemInformation, SystemPreferences, Terminal, TextEdit, and Xcode.


The screenshot above shows Scriptarian’s current ‘dictionary’ imported from MarsEdit, for example, and that below the ‘real’ AppleScript dictionary as viewed in Script Debugger.


As a script development environment, Scriptarian remains excellent, with better code completion and other support tools than Xcode’s Swift Playgrounds. You can export an executable script, which is quite an intriguing feature. This apparently writes your script out as an unsigned Mach-O executable file, which is tiny in comparison with anything produced by Xcode: a simple script weighs in at just 12 KB.

At present, such exported scripts must be run from Terminal’s command line, but can enjoy a fairly independent graphical interface. They appear to depend on runtime support provided by the Scriptarian app, so are not (I think) properly standalone apps. But they are the closest thing that I have seen yet to an AppleScript app. Like AppleScript apps, they pose the next problem of code signing: currently Scriptarian doesn’t offer any facility to sign these command tools, although it may be possible to use Apple’s signing tool codesign in Terminal.

Scriptarian is at once the most fascinating and infuriating puzzle of a product. In some respects – its development environment, Swift language documentation, and pure Swift support – it is at least as good as anything else, and I much prefer it to Xcode’s Swift Playgrounds.

Its AppleScript support has come on a long way since last year, and continuing work to extend its support of app dictionaries will make it more and more suitable as a substitute for AppleScript. However, this now depends increasingly on documentation and examples, which are currently almost absent. Accessing dictionary features is conducted using Swift syntax, but is completely different from AppleScript. Explanations and examples are essential: we cannot be expected to just guess what to do from half a dozen short code snippets.

The other area which is in need of improvement is support for macOS features. For many scripters, FileManager provides a crucial suite of functions, and is one example where Scriptarian remains sufficiently incomplete to be of little use for actually writing and running scripts.

Scriptarian is wonderful value at a mere $10. It is still in a class of one: there is no other accessible app with a friendly interface which gives so much access to the Swift language, macOS, and AppleScript features. SwiftAutomation is a working alternative which can be installed in a Swift development environment such as Xcode, but has not yet been packaged into a similar GUI.

If you write scripts for macOS, Scriptarian is now worth looking at carefully. It is steadily getting closer to what we need, and I hope that its developer can continue with this fascinating project, and see it through to the point where it is more immediately useful and productive.