3. Show of Hands?
• Have you used…
• AppleScript?
• Automator?
• Other form of application scripting?
4. Why Automate?
• Improve productivity
• Avoid repetitive tasks
• Streamline workflows
• Opportunities for experimentation
• Add missing features to OS X apps!
8. Open Scripting Architecture
• Survived the transition to OS X
• Leveraged by OS X to launch applications, open
documents, etc.
• A standard mechanism for interapplication
communication
9. Language Options
• AppleScript (there from the beginning)
• JavaScript for Automation (as of Yosemite)
• Python (PyObjC, py-appscript)
• Ruby (RubyCocoa, RubyOSA)
• And now Swift!
10. Language Options
• AppleScript (there from the beginning)
• JavaScript for Automation (as of Yosemite)
• Python (PyObjC, py-appscript)
• Ruby (RubyCocoa, RubyOSA)
• And now Swift!
11. AppleScript
• A “natural language” programming model
• Primarily geared toward being the “glue”
between apps
• Limited inherent functionality
12. AppleScript
• Can be frustrating to people who are fluent in
“normal” programming languages
• Verbosity is a hallmark
set fileName to "name.jpg"
set sansExtension to text 1 thru ((offset of "." in fileName) - 1) of fileName
13. Swift
• A “primary” language
• Ready access to Cocoa
• Can run Swift scripts using #! convention
• A familiar coding style
let fileName = "name.jpg"
let sansExtension = fileName.stringByDeletingPathExtension
14. Scripting Bridge
• Introduced in Mac OS X Leopard (version 10.5)
• Provides high-level Objective-C access to
scriptable applications
• Can be leveraged in Swift, with a bit of extra
work
15. Scripting Bridge Recipe
• 1 part sdef
• 1 part sdp
• A pinch of manual intervention
• Automate to taste
16. Scripting Definition
• Scriptable applications include resources that
describe their scripting interface
• Can be in a variety of forms
• The sdef command-line utility extracts the
scripting definition
• Writes to standard output in XML format
17. Scripting Definition
• Using sdef
sdef /path/to/App.app > App.sdef
• For the most part, using sdef is “run and forget”
• Until you find out what’s wrong when you run sdp
• Some sdp warnings can be ignored
22. Don’t Run with Scissors
• Using Objective-C header leads to pervasive
AnyObject typing
• Works, but can lead to ambiguity
• For properties, sometimes have to resort to
using valueForKey
• Sometimes leads to awkward method
invocation
23. An Alternative
• Create Swift protocols that cover the generated
Objective-C API
• 👍 Supports rich set of types
• 👍 API translation can be automated
• 👎 Requires optional declaration of all
properties and methods
30. Plan of Attack
• Create frameworks for target applications
• Install in /Library/Frameworks
• Write scripts instead of compiled code
31. By the Way
• Playgrounds don’t fit well
• The Swift REPL could spontaneously combust at
any moment
• What’s a scripter to do?
• Use a text editor
• Edit, run, repeat
32. Script Invocation
• Hash-bang on the first line
#!/usr/bin/xcrun swift -F /Library/Frameworks
• chmod +x SomeScript.swift
35. A Little More Help
import ScriptingBridge
@objc public protocol AcornApplication {…}
extension SBApplication : AcornApplication {}
let acorn = SBApplication
.applicationWithBundleIdentifier(
"com.flyingmeat.Acorn4"
) as! AcornApplication
acorn.taunt!()
36. A Little More Help
import ScriptingBridge
import AcornScripting // Acorn Swift protocols
let acorn = SBApplication
.applicationWithBundleIdentifier(
"com.flyingmeat.Acorn4"
) as! AcornApplication
acorn.taunt!()
37. A Little More Help
import ScriptingUtilities // Helper framework
import AcornScripting // Acorn Swift protocols
let acorn = Application(name: "Acorn")
as! AcornApplication
acorn.taunt!()
38. Where to Put Scripts?
• Short answer: anywhere
• Some applications have special script folders
• Scripting Menu
• Invoke via an Automator Service