Packagemaker: Delivering Applications
Volume Number: 25
Issue Number: 05
Column Tag: Installers
Packagemaker: Delivering Applications
Learn how to build an application installer
for OS X 10.5
By José R.C. Cruz
Introduction
In this article, I will show how to deliver applications for Leopard using an installer package. First, I list situations where an installer package is the better delivery solution. Next, I show how to add an application payload to a package. Then I show how to get the package check for certain target settings. I also show how to get the package choose the right payload for the specific target.
A Survey of Delivery Methods
You can deliver your applications to OS X users in a number of ways. One way is to package the application in a tarball or ZIP archive (Figure 1). When a user double-clicks the archive, the Finder opens the archive with the Archive Utility tool. It then extracts the application and saves it on the same directory as the archive. The user then moves the application to the desired location.
Figure 1. Delivery by tarball
Another way is to package the application in a disk image file (Figure 2). When a user double-clicks the file, the Finder mounts it as a virtual disk volume. The user then copies the application from the image to the correct location. You can also place a link to the preferred directory on that image file as a matter of convenience. You can also have the image file display a ReadMe or License file while being mounted.
Figure 2. Delivery by disk image
Both methods are simple and easy to prepare. They incur zero costs, which makes them popular for open-source and freeware projects. But these methods rely on users knowing how to install the payloads. They also work best if the payload is a single application. A more user-friendly method is to use an installer package.
Delivery by package
Using an installer package as a delivery method has a number of benefits. First, a package can check if the target can run your application. For instance, if the target has the wrong system version, the package tells users of the problem, and then stops the install process. But if the target lacks enough memory, a package can warn those users, yet allow the install process to continue.
A package can install any support files that the application needs. It can route those files to the right locations on the target. It can use SystemStarter to launch those files if necessary. Or it can prompt users to re-login or restart their machines in order to use the application.
A package can handle several variants of the same payload. Assume, for example, you have two variants of the application Foobar. One variant is optimized for PowerPC, the other for x86. The package can first check which CPU the target uses. It then can select and install the right variant for that target.
A package also "forces" users to read important files such as the ReadMe and License files. Users often ignore these files if found in a tarball or disk image. A package also keeps a record of the installation in the /Library/Receipts directory. It then can use this data to handle any upgrades to the application. And a package can run scripts to prepare the target before and after an install session.
But an installer package also has its own downsides. It takes more work to prepare a package than an archive or disk image file. The package is also a bundle format, which needs the use of an archive or disk image file (this is no longer true with Leopard packages). And there are variants of the package format, each variant tuned to a specific version of OS X.
Nevertheless, an installer package is a viable delivery method. Apple itself uses packages to deliver products such as iTunes, iPhoto, and Xcode to its users. These products are prime examples of how an installer package should work.
The Application Payload
Applications come in two forms. Some are executable files. They keep their code and resources in one large file. Some are executable bundles. They keep their code and resources as separate items in one special directory.
PackageMaker 3.0 can handle either format. It also has two new panels wherein you can configure your payload. The Contents panel lets your sets the payload's permission flags, UID, and GID. The Components panel lets you set the relocation and downgrade options of your payload.
The Contents panel
The Contents panel (Figure 3) lists the items that comprise the application payload. It shows the current permissions, UID, and GID of each item. By default, PackageMaker shows the UID and GID that Xcode assigned to the payload and its items. It also shows the octal value 732 as the payload's permissions.
Figure 3. The Contents panel
On the lower left of the panel are the permission controls (red). Use these controls to change the permissions of the selected item from the list. For example, to set the file Info.plist to read-only, first select the file from the list. Then set the checkboxes Read, and clear the checkboxes Write and Execute, for each user type.
Note that changing the permissions of a directory does not change the permissions of its items. Note also that some directories such as .app and Contents must have the Execute flag set. If this flag is not set, the application bundle will not run.
On the lower right of the panel are the UID /GID controls (green). Use these controls to change the UID or GID of the selected item. For instance, to change the UID for Info.plist to root, select the file from the list. Then choose root from the pop-up menu Owner. Again, changing the UID or GID of a directory does not affect its items.
In most cases, you should let the tool assign the correct permissions, UID, and GID to the payload's items. To do so, click the button Apply Recommendations. The tool then updates each item in the payload to the correct set of permissions. It also sets the UID and GID to root and admin respectively.
You can also use the Contents panel to exclude certain items in the payload from the package. For example, to exclude the French.lproj bundle, clear the checkbox next to that bundle's name (Figure 4). When the tool builds the installer package, it does not add French.lproj and its files to that package.
Figure 4. Selecting an item to exclude
Another way to exclude items is with the File Filter dialog (Figure 5). This dialog lists the regex patterns the tool uses to check each items. If the tool finds a matching item, it excludes that item from the package. Those same items will still appear on the list, with their checkboxes set.
To add a pattern to the list, click the '+' button. Then type the string directly on the list. To remove a pattern, select the string from the list, and click the '-' button. To change a pattern, double-click the pattern string on the list. Make sure to click the Save button to keep your changes.
Figure 5. The File Filter dialog
The Components panel
The Components panel (Figure 6) defines how the package handles relocation and downgrades. By default, the package installs its payload at the path set in the Destination field. To let users to change the path, select the checkbox Allow Relocation. Users can then use the Select A Destination panel to select a new destination for the payload.
Figure 6. The Components panel
Also, by default, the package only lets users to do upgrades. If the target has a copy of the payload, the package will replace that copy only with a newer version. To let users install an older version of the payload, set the checkbox Allow Downgrade.
The topics of relocation and downgrades are beyond the scope of this article. I will, however, cover these two topics in a future article. For now, just leave this panel at its default settings.
Preparing The Package
Our demo package Foobar will have two variants of the payload CompositeLab. One variant is for PowerPC targets, the other for Intel targets. The package will check if the target system is version 10.4.4 or newer. It will filter out all target volumes with less than 1 Gbytes of space. It will also warn users if the target has less than 700 Mbytes of physical memory. To keep things simple, we will leave the package's interface elements at their default values.
Start a new project file with PackageMaker. Choose Install Properties from the Project menu. Set the properties dialog as shown in Figure 7. This sets the package's base ID. We're using com.mactech, but feel free to use your own ID.
The dialog also sets the package format based on the minimum target system. If you choose 10.4, the tool will use the distribution package format. This is a bundle format. It stores its localized text, metadata, and scripts in the XML file distribution.dist. It also stores each payload as separate component packages. But like all bundle formats, you must use a tarball or image file to send the package to your users.
Now if you choose 10.5, the tool will use the new Leopard package format. Unlike previous formats, which are bundles, the Leopard format is a flat file. It is simpler to distribute, as it removes the need for a tarball or disk image file. It does not, however, let you change the package after building it. It is also supported only on MacOS X 10.5.
Figure 7. Setting the Install Properties
Next, click the icon Foobar at the top of the payload list. Select the Configuration tab to display the editor subpanel. Update the subpanel as shown in Figure 8. The settings tell the package to display only the Custom Install panel. It also tells the package to let users choose the desired target volume.
Figure 8. Configuring the package
Adding the payloads
Choose Add Contents from the Project menu. Select the application Composite (PPC).app with the sheet dialog, and click the Choose button. PackageMaker then adds an entry for that payload in the payload list. It also updates its Configuration panel as shown in Figure 9. Use the same steps to select the application Composite (x86).app.
Figure 9. Configuring the payload
Notice the tool sets the destination path for both payloads to /Applications. The tool also sets the checkbox Allow custom location. It sets the pop-up menu Restart Action to None, and selects the checkbox Require admin authentication.
Configuring the contents
Select the payload CompositeLab (PPC) from the payload list. Click the Contents tab on the editor panel. You should see the payload bundle displayed on the Contents list. To view the bundle's items, click the triangle next to its name (Figure 10).
Figure 10. Configuring the payload contents
As stated earlier, PackageMaker sets the UID and GID of each item to your username and group. Now click the button Apply Recommendations. The tool will change the UID and GID to root and admin. Apple uses these same settings for its Cocoa products.
Locate and select the file BBalls.icns from the Contents list. Using the permission controls, set that file as read-only for all users, you included. Repeat the same steps for the file Info.plist. Leave the permissions for the rest of the bundle items unchanged.
Now, select the payload CompositeLab (x86) from the payload list. Use the same steps to configure the bundle contents of that payload.
Setting target requirements
Now, click the Foobar icon at the top of the payload list. Select the Requirements tab on the editor panel. Then click the '+' button at the bottom left of the list to display the Requirements Editor.
Update the editor as shown in Figure 11. Click the OK button to save your settings. These settings tell the package to check if the target OS is at least version 10.4.4. If the check proves true, the package continues the install session. If false, it displays the failure message and ends the session.
Figure 11. Checking for OS version
Notice that there are actually two checks for OS versions. One checks the system version, the other the target version. System is where you are hosting the package. It is where you opened the package using Installer. Target is where you want to install the payload. It also has the volumes that may contain the payload.
In most cases, system and target refer to the same thing. This is the assumption I make in this article. But there are cases when system and target are not the same. Figure 12 is one example of such case. Here, the package is on a server running OS X 10.4. It installs its payload onto a network client running OS X 10.5. So, in this example, the 10.4 server is the system and the 10.5 client is the target.
Figure 12. Delivery via a network
Time to add the memory check. Click the '+' button to display the Requirements Editor. Update the editor as shown in Figure 13. Click the OK button to save your settings. These settings tell the package to check if the target has at least 700 Mbytes of physical memory. If the check proved false, the package displays the failure message. Notice that the memory amount is expressed in bytes.
Figure 13. Checking for physical memory
Unlike the OS version check, the memory check only checks the system. But like the OS version check, the memory check also ends the session if it is false. To change this behavior, select its entry on the Requirements list. Click the Required column, and change the entry from Required to Optional (Figure 14). Now, when the check proved false, it will still let users continue with the install session.
Figure 14. Making the check optional
Bring up the Requirements Editor once again. This time, update the editor as shown in Figure 15. Click the OK button to save the settings. These settings tell the package to check each mounted volume on the target. If it finds a volume with less than 700 Mbytes of free space, the package will not install its payload on that volume. It will also display the specified failure message for that volume.
Figure 15. Checking for volume space
The package runs each check at different points in the install session. It runs the check for the target's OS version and memory right after it shows its Welcome panel. But it runs the volume check after it shows the Select A Destination panel. Knowing where each check is done will help debug any problems found in the package.
Configuring the choices
The next step is to configure each payload choice. Click the choice CompositeLab (PPC) from the payload list. Select the Configuration tab on the editor panel. Update the panel as shown in Figure 16. These settings enable and select the choice by default. They also set the description and tooltip message of this choice.
Figure 16. Configuring the PowerPC payload
Now select the Requirements tab from the editor panel. Click the '+' button to display the Requirements Editor. Then update the editor as shown in Figure 17. These settings tell the package to check the system CPU using a sysctl() call. If the CPU is a PowerPC, the package leaves the choice unchanged. Otherwise, the package deselects and disables the choice.
Figure 17. Checking for a PowerPC CPU
Next, click the payload choice CompositeLab (x86). Update its Configuration subpanel as shown in Figure 18. Again, the settings select and enable this choice by default. They also set the description and tooltip message of this choice.
Figure 18. Configuring the x86 payload
Go to the Requirements subpanel and display its editor. Update the editor as shown in Figure 19. Again, the settings tell the package to check the system CPU using a sysctl() call. If the CPU is an x86 or Intel processor, the package leaves the choice unchanged. Otherwise, it deselects and disables the choice.
Figure 19. Checking for an x86 CPU
Testing The Package
I will now show how to test your package. First, choose Build from the Project menu. PackageMaker then prompts you for a package name. Type Foobar on the Save File dialog and click the Save button.
Then go to the Finder and locate the Foobar package. Double-click the package to start an install session. If all goes well, the package should display its Welcome panel.
Testing requirements
After the package displays its Welcome panel, it first runs the OS version check. If your target is running 10.5, it should pass the OS version check. But if it is running 10.4.3 or older, you should get the error dialog in Figure 20. Clicking the Close button should end the install session. If these do not happen, recheck your requirements settings and rebuild the package.
The OS version check, however, does not apply if the package uses the new flat file format. Again, this is because only 10.5 will support the new format.
Figure 20. The OS version check fails
Once the target passes the OS version check, the package then runs the memory check. If the target has less than 700 Mbytes of memory, the package should display the warning dialog in Figure 21. But clicking the OK button should not end the install session. Instead, it should dismiss the dialog and return you to the Welcome panel.
Figure 21. The memory check has failed
Now, click the Continue button on the Welcome panel. The package then displays the Select A Destination panel (Figure 22), showing a list of target volumes. It then runs the volume check on each mounted volume. If a volume fails the check, its icon gets a stop badge. Selecting that volume will display the error message. But if a volume passes the check, selecting that volume displays a green arrow on its icon (Figure 23). And, placing the cursor over any volume icon, pass or fail, displays that volume's mount info.
Figure 22. Selecting a volume that failed the check
Figure 23. Selecting a volume that passed the check
Testing choices
After you have selected a target volume, click the Continue button to go to the Custom Install panel. If the package does not display this panel, you may have disabled this setting. Make sure you have configured your package as shown in Figure 8.
On a PowerPC target, the package should enable and selected the payload CompositeLab (PPC). It should also disable the payload CompositeLab (x86) as shown in Figure 24. The reverse should happen if the target is an Intel one. Also, if you select either choice, you should see its description displayed on the field below the choice list. And if you place the arrow cursor over each choice, you should see the tooltip message for that choice.
Figure 24. Choosing the PowerPC payload
If none of these happen, check again your settings for that choice. You may also want to check the target to see if it returns a different sysctl() value. Start a Terminal session and type the following at the prompt.
sysctl hw.cputype
If the target returns a value different from 18 or 7, use that value to enable the right payload.
Testing payloads
Once you confirmed the right payload selected, click the Continue button to display the Standard Install panel. Then click the Install button to install the payload.
First, the package asks you to enter an admin password. Enter the password and click the OK button. If the password is correct, the package then installs its payload onto the target volume. It then displays the Conclusion panel shown in Figure 25.
Figure 25. The concluding panel
If you enter the wrong password thrice, the package should return you to the Standard Install panel. Also, if the package fails to install its package, it should display a red circle with a white cross on its Conclusions panel.
Now, check the target volume that you have selected. You should find the payload inside an Application directory. You should also find a /Library/Receipts directory at the volume's top level. That directory's contents should be the files shown in Figure 26. These files serve as a record of your install session.
Figure 26. The results of the installation
If you find these items installed on the target, your install session is indeed successful.
Concluding Remarks
This article showed some of the benefits of using an installer package to deliver applications. The package can install the right payload for a given target. It can check the target for resources needed by the payload. It can set the correct permissions, UID, and GID to the payload. It also makes a record of the install session on the target.
Next time, I will cover the new scripting features of PackageMaker 3.0. I will show how to add an installer script to the package. I will also show how to write and edit a script using the Requirements Editor.
Until next time, relax and have a cup of tea.
Bibliography and References
Apple Computers. PackageMaker Users Guide. 2007 Jul 23. Copyright 2007. Apple Computers, Inc. Online:
http://developer.apple.com/DOCUMENTATION/DeveloperTools/Conceptual/PackageMakerUserGuide/Introduction/chapter_1_section_1.html
Apple Computers. Software Delivery Guide. 2006 Jul 24. Copyright 2006. Apple Computers, Inc. Online:
http://developer.apple.com/documentation/DeveloperTools/Conceptual/SoftwareDistribution/Introduction/chapter_1_section_1.html
Apple Computers. Installing Your Application on MacOS X: Guidelines for Developers. 2005 Jul 07. Copyright 2008. Apple Computers, Inc. Online:
http://developer.apple.com/tools/installerpolicy.html