Polishing your own apps

Creating a polished, double-clickable Mac application does not require you to become an Xcode Black Belt, nor to quaff Cocoa. Here is a summary of what you need to do.

Producing a thoroughly professional application for Mac OS X, complete with localised dialogs and more, is not a trivial task, although there are several tools that create rudimentary forms. Whether you are working in AppleScript, its friendly Automator front-end, or want instead to run a command line tool or Java application, it can be relatively straightforward to package it up into a ‘real’ application, complete with custom icon and Finder information.

.app structure

Take a minimal application, such as one generated by Script Editor or Automator, apart and you will see the standard structure (Control-click for Finder’s contextual menu, and select Show Package Contents). An application is a regular folder whose name ends with the .app extension, which Finder treats specially. Inside that top-level .app folder is a single folder named Contents, which in turn contains the essential components required by Mac OS X applications.

appcontentsAlthough you can have additional custom folders and files, the standard minimum for an application consists of an XML information property list (Info.plist), standard Finder information (PkgInfo), and two folders named MacOS and Resources. You will come across additions to this, of which the most common is another XML property list containing version details (version.plist). To take advantage of the latest security features, all commercial and many other applications also have a _CodeSignature folder containing a single file, CodeResources, to which there is also an alias placed within the top Contents folder; code signatures require registration with Apple, trust certificates, and more which is beyond the normal amateur.

The MacOS folder contains compiled executable code, and sometimes compiled libraries to support that. In the case of AppleScript applications, this is an Application Stub file (the precise name varies with implementation), but grander applications normally include their much more substantial code files, dynamic libraries (.dylib), and any self-contained tools that the main application might call.

The Resources folder is more of a rag-bag that usually has everything else needed by the application thrown into it. This includes the custom icon, in a .icns file, other resources in a .rsrc file, any graphic elements in the form of TIFF and other image files, and more. Applications that support different localised languages do so by means of language-specific .lproj folders here, each containing special .nib bundles that are actually folders full of resources; these are normally constructed using tools in Xcode.

Other folders commonly found in more substantial applications, inside the Contents folder, include Frameworks (for custom code frameworks to support bespoke printing and other features), Library (for add-ons such as Automator actions), and PlugIns (for those that are integrated with the application and not added on).

Info.plist

Info.plist holds the most important application-wide keys, and studying a few examples should quickly enable you to hand-craft your own using an XML or text editor. Essential keys that you should take care to define are: CFBundleExecutable, which names the executable code (in the MacOS folder) to be launched when the application is started; CFBundleIconFile, which names the file containing the application icons (in the Resources folder); CFBundleName, which gives the application name; CFBundlePackageType, which specifies the bundle as being an application (APPL); and CFBundleSignature, which gives the unique four-character signature. Such signatures are properly registered and allocated to developers, but so long as you choose one that is not used by any other application it should suffice for everyday use.

Other useful keys are to be seen in standard applications, particularly recent Apple products, and include: CFBundleVersion, CFBundleShortVersionString, CFBundleGetInfoString, CFBundleIdentifier, LSMinimumSystemVersion, and LSMinimumSystemVersionByArchitecture. Applications that create and use their own document types specify these in XML dictionaries under the CFBundleDocumentTypes and CFBundleURLTypes keys, but it is difficult to build such intricate systems by hand, and you are best off using Xcode to handle those.

PkgInfo is a simple text file contain the four characters ‘APPL’ (also given in the CFBundlePackageType key), and the four character signature of the application as given in the CFBundleSignature key. Where provided, version.plist is a short XML property list giving key data for BuildVersion, CFBundleShortVersionString, CFBundleVersion, ProductBuildVersion, ProjectName, and SourceVersion. These are easy to crib from a commercial application, but should match the keys in Info.plist, of course.

Putting it together

A relatively straightforward way of using these techniques to turn a Java executable, shell command, or similar, into a polished double-clickable application is to first form it into an AppleScript application, then customise that to create a proper .app bundle. At its heart, the AppleScript may be as simple as calling a single command. For example, this might be launching a .jar file using the java tool
java myapp.jar

Wrap this into its AppleScript call of
do shell script “java myapp.jar”

If you need the code to launch in a Terminal window, this could be elaborated into something along the lines of
tell application "Terminal"
activate
do script “runmytool -optionA myfile”
end tell

This article explains in more technical detail what happens when an app is started up.

Paths

The most important problem that you now have to solve is to ensure that the required components can all be found in their folder paths. Standard shell commands, such as java, should be readily accessible from the runtime environment, but components such as .jar files will need to be correctly located if you place them in the Resources folder of your application bundle. If your application is only allowed to run from the top-level Applications folder, you can get away with a command line like
cd /Applications/MyApp.app/Contents/Resources; ./myapp
which first changes folder to the standard Resources folder within your application bundle, and then runs the shell command myapp from there.

However to make your application more portable you will need to use relative folder locations. AppleScript run as a script (.scpt) or an application, even if it is moved to the top-level Applications folder, will always see your Home folder (~ in Unix shorthand) as its home folder, so you will need to point it at the application Contents folder, or the Resources folder within that. This is more easily accomplished within Xcode, which will also cater better for applications that are to be launched within various OS X Server client configurations.

You can then customise that AppleScript application by placing .jar and other key files inside its Resources folder, designing your own icons for the application, and so on, making changes to the property lists and other components as you need. Keep careful backup copies of the .app bundle as you do this, and test it out at each stage, so that you can rectify any errors or bugs as they arise.

Apple provides extensive documentation with the Xcode Software Development Kit (SDK, free from the App Store) that details the keys available in Info.plist and many of the twists and turns that application bundles can take. Looking through the internals of commercial applications helps make sense of it all, and should enable you to turn a quick and dirty AppleScript or Automator tool into something that looks thoroughly professional.

Technique: Icon Design

Icons used to be placed in fairly conventional form inside a standard icon image (.icns) file in the application bundle. Crafting an icon set was then a matter of creating a high resolution master, with its icon mask in the alpha channel, then scaling it down to lower sizes. The standard set used to be 512, 256, 128, 32, and 16 pixels square.

appassestcatcreateThis has changed with the advent of Retina displays, and the added complexity of support for iOS devices (and their Retina displays) down to the Watch, and vector graphics. Probably the best route now is to use your preferred graphics editor to create a square icon design at 1024 by 1024 pixels size, then use one of the many available tools such as Asset Catalog Creator (App Store, £3.99) to turn that into an Asset Catalog. Alternatively you can use a different tool to stick to old-style icon sets if you prefer.

Tools: Xcode

Once a flagship feature, AppleScript development remains in Apple’s Xcode SDK, but is now played down. Remaining example projects are in old formats, thus are difficult to import into a current version. However this does not make Xcode and its tools any less useful for developing AppleScript applications.

appxcodestartTo create a new AppleScript application project, start Xcode, and select the New Project… command in the File menu. In the New Project dialog, select Other in the OS X section. From the options offered in the main view, select the Cocoa-AppleScript icon, then click on the Next button. You will then need to provide a product name and organisation details. Normally AppleScript apps will not be document-based.

The resulting project looks incredibly complicated, but even if you are too daunted to anything more, select the Build command in the Product menu, and all the files needed for an empty application will be collected into your project folder. You can then run it by clicking the Run tool, although this empty application does nothing except open a blank window. It has, though, all the hooks needed to support a proper human interface.

appxcodesourceIf you fancy trying your hand at building a more functional AppleScript Studio application, simply paste your script into that .applescript file and give it a test.

Updated from the original, which was first published in MacUser volume 26 issue 18, 2010.