Hey Bodie,
Buy UI Browser. It’s not inexpensive, but it will save you hours of frustration. (I’ve been using it since 2005.)
Join the UI Browser User Group:
https://groups.yahoo.com/neo/groups/uibrowser/info
There is NO good, methodical documentation for UI-Scripting, so you have to dissect other people’s scripts, ask questions, and gain experience.
You’ll find quite a few of mine on the Keyboard Maestro forum.
Keyboard Maestro is by far the most powerful macro utility available for the macOS today, and I’ve been using it since early 2004 when v1.0 came out.
BUT – I don’t use it to run most of my AppleScripts. I use FastScripts which is a much improved analog of Apple’s AppleScript menu (and probably the most productive $9.95 I’ve ever spent on software.)
Why FastScripts?
FastScripts is very easy to use.
Unlike Apple’s AppleScript menu, FastScripts has the ability to assign app-specific and global keyboard shortcuts.
It has a keyboard shortcut to open the main menu, so you can type-select.
The FastScripts menu works more reliably with type-select than does the Keyboard Maestro status menu.
I have nearly 600 AppleScripts that are mostly hotkey-driven.
I run AppleScripts from compiled-script-files rather than text-scripts, because there is a distinct performance advantage – FastScripts is a more convenient mechanism for managing AppleScripts on-disk than Keyboard Maestro.
I can open a script for editing by depressing the Option-key when selecting it from the FastScripts menu.
I can reveal the script in the Finder by depressing the Shift-key when selecting it from the FastScripts menu.
FastScripts uses a different mechanism to run AppleScripts than Keyboard Maestro, so I can use it to test with if Keyboard Maestro is choking on something and see whether KM is the problem or not.
Because of the different AppleScript-runner mechanism, FastScripts will run some AppleScriptObjC code that Keyboard Maestro won’t.
FastScripts gives me a second means of running AppleScripts and shell scripts, so I can offload jobs that take time on it (or KM) and still have the other unencumbered.
I do drive a very few pure AppleScript macros from Keyboard Maestro, because on occasion I get better performance – but I’m more likely to use AppleScripts with Keyboard Maestro when they are part of a larger macro.
FastScripts lets me work with the Keyboard Maestro Editor without involving Keyboard Maestro which is especially useful if I’ve quit the engine.
There are other reasons that have cropped up over the last 13 years, but I don’t remember all of them.
FastScripts uses ~/Library/Scripts as its base folder.
Global scripts go directly in that folder (or subfolders).
App-Specific scripts go in the Applications subfolder.
~/Library/Scripts/Applications
It’s very straightforward.
I have a folder for working scripts bound to a hotkey in the Finder and in Default Folder, and I have it indexed in LaunchBar as well – so I have very quick access to them.
I have a script that creates my normal script header.
I have an abbreviated dev-header for when I need to track what I’m working on but don’t want the clutter of the full header.
I have another script that will save the script I’m working on in my script library based on the app-name or other routing information in the header.
The library is for reference and not for running scripts, and it too is indexed in LaunchBar.
~/Documents/Scripts (Library)/
So – between LaunchBar and Spotlight I can very quickly (usually) find saved code I want to reuse.
(This doesn’t include all the boilerplate and handlers I have in Script Debugger’s text-expansions and in Typinator.)
Well done!
UI elements can often be called by name, and there are other tricks.
I use UI Browser to explore the UI of a given app, and I use it to grab my initial reference to an element.
I have a script that turns UI Browser’s flat reference into a hierarchical one.
Then I usually use this construct for analyzing the node I’m in – in combination with Script Debugger’s best view result window.
set diagnosticsList to {¬
“----- PROPERTIES -----”, ¬
properties, ¬
“----- UI ELEMENTS -----”, ¬
UI elements, ¬
“----- ATTRIBUTES -----”, ¬
attributes, ¬
“----- ACTIONS -----”, ¬
actions, ¬
“----- END -----”}
I have it in a text-substitution, so it’s easy to emplace.
You can get name and value (and other aspects) of UI elements, and these can frequently be used to reference them.
I often refer to the front window of an app like this to filter out floating windows and such:
tell (first window whose subrole is "AXStandardWindow")
Here’s the practical example of getting Safari’s uni-field:
- UI Browser is used in combination with one of its keyboard shortcuts to identify the field.
- Cmd-Opt-R is used to send the reference to the field to Script Debugger.
text field 1 of UI element 1 of group 2 of tool bar 1 of window "Best Practices for GUI Scripting - AppleScript - Late Night Software Ltd." of application process "Safari"
- I select the line and hit Ctrl-Shift-U to activate my hierarchical script and get this:
tell application process "Safari"
tell window "Best Practices for GUI Scripting - AppleScript - Late Night Software Ltd."
tell toolbar 1
tell group 2
tell UI element 1
end tell
end tell
end tell
end tell
end tell
** At some point I’ll automate adding the System Events tell-app-block.
- I change the above to:
tell application "System Events"
tell application process "Safari"
tell (first window whose subrole is "AXStandardWindow")
tell toolbar 1
tell group 2
tell UI element 1
it
end tell
end tell
end tell
end tell
end tell
end tell
-
Then I use Script Debugger’s result window in Best-mode to explore the UI element.
-
With a little more information I might change the script some more:
tell application "System Events"
tell application process "Safari"
tell (first window whose subrole is "AXStandardWindow")
tell toolbar 1
tell group 2
tell (first UI element whose role is "AXSafariAddressAndSearchField")
it
end tell
end tell
end tell
end tell
end tell
end tell
- Sometimes I prefer to explore with Script Debugger Source-mode, and I’ll do this:
tell application "System Events"
tell application process "Safari"
tell (first window whose subrole is "AXStandardWindow")
tell toolbar 1
tell group 2
tell (first UI element whose role is "AXSafariAddressAndSearchField")
set diagnosticsList to {¬
"----- PROPERTIES -----", ¬
properties, ¬
"----- UI ELEMENTS -----", ¬
UI elements, ¬
"----- ATTRIBUTES -----", ¬
attributes, ¬
"----- ACTIONS -----", ¬
actions, ¬
"----- END -----"}
end tell
end tell
end tell
end tell
end tell
end tell
I can toggle this between Source and Best modes and get the best of both worlds.
So – you opened a can of worms didn’t you.
There’s a reason why there are quite a few books about AppleScript.
But you cannot learn AppleScript well from a book, because no book covers the wide variety of scriptable apps out there (and each one has its quirks).
You need one or two good books on AppleScript to learn basics and have for reference.
You need to join available AppleScript communities – as you have with this forum – but let me also suggest MacScripter.net and the Applescript Users List.
(If you’re interested in automation beyond scripting then I suggest you look carefully at Keyboard Maestro. The Keyboard Maestro community is strong.)
You need some personal mentoring. If you don’t have a few go-to-guys then you’ll end up banging your head against the wall far too often.
Script Debugger too is a total no-brainer for anyone who is really interested in becoming more productive through the use of AppleScript. (Especially since the price has been lowered.)
Most people just do not GET how much SD improves the AppleScript learning, coding, and debugging experience.
I think I spent 3 days with Script Debugger v1.0, before I paid the (then) hefty sum of $129.95 for it in 1996(?), but I knew in 3 hours that it was far superior to Scripter and that I should buy it if I wanted to continue with AppleScript.
Since that day Script Debugger has run 24/7 on my system.
-Chris