Downloading & Using FancyDroplet


(Mark Alldritt) #1

As a side project I am working on an improved AppleScript droplet shell. My goal is to create a better AppleScript droplet experience by providing a better UI for receiving dropped files and offering a way of picking files to process via integrated Spotlight document searching (you’ll recognize this as being based on Script Debugger’s Open Quickly feature). Additionally, I want to give droplet scripts and opportunity to clean up if the user stops or quits the script.

##Downloading FancyDroplet

I have a very rough prototype of this new droplet shell working. I thought I would share it with you all to get some feedback.

CAUTION: This is not suitable for the faint of heart. There is no tooling for creating versions of FancyDroplet for your own scripts. You’ll have to manipulate the contents of FancyDroplet manually.

There are some key features offered by the standard AppleScript droplet shell which are missing:

  1. Does not operate as an applet (i.e. droplets only!)
  2. Does not display a startup screen
  3. Does not support on idle handlers
  4. Does not support AppleScript handler invocations from other applications

The Current FancyDroplet is: (243.1 KB) (243.1 KB)

##Embedding Your Script in FancyDroplet

To embed your script within FancyDroplet, follow these steps:

  1. Duplicate, giving it a suitable name

  2. Select your copy of FancyDroplet in the Finder, and issue the Show Package Contents command

  3. Add this code to your script:

    --	Properties configuring the droplet shell
    property appletDropImage : "CSVDocumentIcon"
    property appletDropName : "Drop your CSV files here"
    property appletSearchName : "Find CSV files"
    property appletSearchImage : "CSVBadge"

    You can alter the values of these properties as you see fit. The appletDropImage and appletSearchImage properties should contain the name (without filename extension) of a image file located within the droplet bundle’s Resources folder. If you don’t want icons for the drop image or search image, specify missing value.

  4. Replace main.scpt with your script’s .scpt file, making sure to call name the file main.scpt.

  5. Edit the Info.plist file

    Here are the items you’ll need to change:

    • The Bundle Name (should match the file name you’ve chosen)
    • The Bundle Identifier (com.yourdomain.scriptname)
    • The Copyright Notice
    • The Document Types
      Change the Document Type Name to your document type
      Change the Document Content Type UTIs array to include the UTIs (Uniform Type Identifier) for document types you want to handle. You can also filter acceptable files using AppleScript (see Advanced File Filtering)
    • By default, FancyDroplet remains open after processing dropped files. If you want FancyDroplet to quit after processing files, change the LNSStayOpen property value to NO:
  6. Codesign your finished script

    FancyDroplet is signed with my code signing identity. When you alter your copy to embed your script, the existing code signing will be invalidated and the Mac OS will complain that the script is damaged. You may also experience problems where FancyDroplet’s window appears behind other application windows.

    To codesign your copy of FancyDroplet, you can issue the following command in the Terminal application:

    codesign --force --deep --sign "<codesignidentity>" -i <bundleID> /path/to/your/copy/of/

    Were <codesignidentity> is your Apple code signing identity (mine is “Developer ID Application: Mark Alldritt”) and <bundleID> is whatevery you entered for the bundle ID in the Info.plist file.

That’s it! Your copy of FancyApplet should work when double-clicked or when files are dropped into its icon using the Finder. You should also be able to distribute your copy of FancyApplet to others.

Handling Stop & Quit

One area of the standard applet shell I want to improve is the handling of cancelling a running script. The standard shell offers a Done button and responds to Command-.. When you press done or quit the application, the script simply stops. I want to provide some way for the script to respond to this and close down gracefully.

FancyDroplet generates a user cancelled exception (-128) when the user presses the done button or quits the applet. You can place an AppleScript try/on error/end try block around your code to catch this exception and act appropriatly. FancyApplet provides the boolean appletIsQuitting property so that you can determine if the user is quitting or simply stopping your script.

Here’s an example:

use AppleScript version "2.4" -- Yosemite (10.10) or later
use scripting additions

--	Properties configuting the droplet shell
property appletDropImage : "CSVDocumentIcon"
property appletDropName : "Drop your CSV files here"
property appletSearchName : "Find CSV files"
property appletSearchImage : "CSVBadge"

global appletIsQuitting -- let the AppleScript compiler know about this runtime defined property

on open theFiles
		repeat with aFile in theFiles
			-- process aFile in some way...
		end repeat
	on error number -128 -- userCancelledErr
		if appletIsQuitting then
			set alertResult to display alert "Quitting!" message "This script has been interrupted because the applet has been quit." buttons {"Stop", "Quit"} default button "Quit"
			if button returned of alertResult is "Stop" then
				error number 0 -- clear the userCancelledErr to prevent the applet from quitting
			end if
			display alert "Stopped!" message "This script has been interrupted because the Stop button has been pressed." buttons "Stop" default button "Stop"
		end if
	end try
end open

If you do not provide an on error number -128 block to catch this exception, FancyDroplet will stop your script immediatly just as the standard AppleScript droplet shell does.

NOTE: FancyApplet will receive the user cancelled exception (-128) when the script finishes unless you generate another exception. You’ll notice the error number 0 statment in my example which has the effect of preventing FancyApplet from quitting.

NOTE: The appletIsQuitting identifier must be defined using a global or property statment. Failure to do this will cause AppleScript to fail to see this identifier and throw an error when you try and get its value.

Stadnard Additions

The standard AppleScript droplet shell displays alerts and file selection panels as applicatioin-modal windows. I find this irritating so FancyDroplet displays panels generated with the following commands as sheets:

  • display alert
  • choose file
  • choose folder
  • choose file name

In the future I’ll be adding implementations for display dialog and choose from list.

For example, this statement:

display alert "Alert Message" message "Alert Description" buttons {"Button 1", "Button 2", "Button 3"} default button "Button 2"

Produces this panel in the standard AppleScript droplet shell:

And appears like this in FancyDroplet:

Advanced File Filtering

There may be times when Uniform Type Identifiers are insufficnent for identifying the types of files your script can process. FancyDroplet allows you to filter the files in AppleScript be defining a on appletFileIsAcceptable(theFile) handler:

on appletFileIsAcceptable(theFile)
	return true
end appletFileIsAcceptable

This handler is called after files have been filtered by their Uniform Type Identifier. I strongly recommend using Uniform Type Identifiers to filter files in combination with the appletFileIsAcceptable handler to minimize performance issues. The appletFileIsAcceptable handler must be FAST as it is used frequently to validate file drops and spotlight search results.

The Future

As I mentioned above, I plan to add sheet versions of more of the Standard Additions commands that present panels. I may also provide a means of disabling my versions of Standard Additions commands for those that prefer the standard implementation.

I expect to provide a tool for deploying scripts with FancyDroplet. This may become a feature of Script Debugger at some point, but I’m not making any promises.

I have some ideas for handling the AppleScript log statement in FancyDroplet to make debugging a little simpler.


I welcome all comments, suggestions and feedback. Please visit the FancyApplet section of the Late Night Software forum for information and discussion relating to FancyApplet.

About the FancyDroplet category
Introducing FancyDroplet
Add Sparkle (for check updates) to Applescript application?
Introducing FancyDroplet
(Mark Alldritt) #2

(Mark Alldritt) #3