Important: The information in this document is obsolete and should not be used for new development.
If you supply version information in the correct format as part of bundled software you create, PackageMaker can gather and store the information in your package file, and Installer can use it to make intelligent decisions about when to replace outdated software during an installation.
This feature provides Installer with an efficient mechanism for determining which files in a package need to be installed, and can lead to a faster installation. This mechanism works as follows:
You supply version information in a version property list file named version.plist
in any application, framework, or other bundles in your installation package.
When you create a package, PackageMaker automatically searches for version property list files in your software, combines them into another property list named BundleVersions.plist
, and stores that list in the package.
During an upgrade installation, Installer can compare version property list files in the previously installed software with those in its bundle versions list. If the version in the target is newer than the version in the package, Installer skips the step of installing that software.
The following sections describe this process, and the bundle versions and version property lists, in more detail.
Note: See “Installs and Upgrades” for information on how Installer determines whether an installation is an upgrade or an install.
Supplying Version Information for Your Software
The BundleVersions.plist File
How Installer Uses Bundle Versions Information
How Installer Computes a Version
Testing With Bundle Versions
In addition to the version information you typically supply in any bundled software, you can add a small property list file that provides Installer with version information about your software. This file can be stored anywhere in the bundle, must have the name version.plist
, and should contain information similar to that shown in Listing 1. Of the keys shown in Listing 1, the most important to supply are BuildVersion
, CFBundleShortVersionString
, and SourceVersion
.
Listing 1 Contents of a version.plist file for a beta release of PackageMaker
<dict> |
<key>BuildVersion</key> |
<string>17</string> |
<key>CFBundleShortVersionString</key> |
<string>1.1</string> |
<key>CFBundleVersion</key> |
<string>1.1</string> |
<key>ProjectName</key> |
<string>PackageMaker</string> |
<key>ReleaseStatus</key> |
<string>Beta</string> |
<key>SourceVersion</key> |
<string>200000</string> |
</dict> |
The BundleVersions.plist
file (or bundle versions file) is a property list file created by PackageMaker when it creates an installation package. The file contains the contents of any version property list files found by scanning the items contained in the archive of files to be installed.The bundle versions file is stored in a package’s Resources
directory and is not localized.
The bundle versions file contains a dictionary of dictionaries. For each top-level dictionary, the key is the path to the version.plist
corresponding to one of the bundles being installed. The value of this key is the contents of the version.plist
referenced by the path in the key.
For example, suppose that there exists an installation package for the latest version of ColorSync Utility and CPU Monitor. The bundle versions file might look like the one shown in Listing 2.
Listing 2 A BundleVersions.plist with versions for two bundles
<?xml version="1.0" encoding="UTF-8"?> |
<!DOCTYPE plist SYSTEM "file://localhost/System/Library/DTDs/PropertyList.dtd"> |
<plist version="0.9"> |
<dict> |
<key>./Applications/Utilities/ColorSync Utility.app/Contents/version.plist</key> |
<dict> |
<key>BuildVersion</key> |
<string>19</string> |
<key>CFBundleShortVersionString</key> |
<string>4.0</string> |
<key>CFBundleVersion</key> |
<string>4.0</string> |
<key>ProjectName</key> |
<string>ColorSyncEtc</string> |
<key>ReleaseStatus</key> |
<string>GM</string> |
<key>SourceVersion</key> |
<string>81</string> |
</dict> |
<key>./Applications/Utilities/CPU Monitor.app/Contents/version.plist</key> |
<dict> |
<key>BuildVersion</key> |
<string>35</string> |
<key>CFBundleShortVersionString</key> |
<string>1.0</string> |
<key>CFBundleVersion</key> |
<string>23</string> |
<key>ProjectName</key> |
<string>CPUMonitor</string> |
<key>ReleaseStatus</key> |
<string>GM</string> |
<key>SourceVersion</key> |
<string>23.1</string> |
</dict> |
</dict> |
</plist> |
Installer reads the contents of the bundle versions file to determine the versions of the items it is installing. For each version.plist
path referenced in the bundle versions file, Installer looks for a corresponding path on the user’s target volume. If the item exists, Installer reads the version.plist
file from disk and compares the versions computed from the two version.plist
files (see “How Installer Computes a Version” for details).
If the version on the target volume is newer than the one in the package being installed, Installer determines the path to the owner of the version.plist
. For example, if Installer encounters a path to a version property list of ./Applications/iTunes.app/Contents/version.plist
, Installer knows that the path to the owner of this property list is ./Applications/iTunes.app
. After determining the owner, Installer prunes any paths beginning with ./Applications/iTunes.app
from the list of paths it will be installing. In this way, Installer can selectively filter out items in the package that would be downgrading items on a user’s disk.
If the version number on the target volume is equal to or less than that being installed, or for software for which it doesn’t find a version property list, Installer allows all files in the bundle being examined to be installed.
For something like a package that installs only localized resources and not the application itself, it is still appropriate to include the version.plist
file for the application that owns the resources in the bundle versions file. Installer can then skip installing localized resources if an application on disk is newer than the one described in the bundle versions file of the package.
A shortcoming of this technology is that it currently will not prevent resources from a newer version of a bundle from being installed into an older version of a bundle. For example, it would be possible to install a package containing only Chinese resources for iTunes 5.0 (if such a version existed) into a copy of iTunes 2.0 (or anything less than 5.0).
To create a version from a version.plist
file, Installer computes a 5-tuple from three keys in the version.plist
file: the CFBundleShortVersionString
key, the SourceVersion
key, and the BuildVersion
key. For a 5-tuple of the form a.b.c.d.e, a.b.c is obtained from the value of CFBundleShortVersionString
, d is obtained from the value of SourceVersion
, and e is obtained from the value of BuildVersion
. If any key is missing, the corresponding element is replaced with 0.
The fourth and fifth elements of the 5-tuple are created from the integer values of SourceVersion
and BuildVersion
. If the only difference between two submissions is that the SourceVersion field changed from 1.8.4GMc2
to 1.8.4GMc3
, Installer treats them as the same because the integer values of both of these is 1. For Installer to be able to distinguish between two copies of a bundle, either the SourceVersion
needs to change for each submission, or the CFBundleShortVersionString
needs to change, such that the integer values can be differentiated.
The accuracy of the version information as well as the correctness of installation may be judged by manually installing the package with the Installer application, located in /Applications/Utilities
. Open the installation package and choose File > Show Log. The Installer log can be saved to disk or printed by clicking the Save or Print buttons in the Installer Log window. If there are any version conflicts, the resulting log contains output similar to that shown in Listing 3.
Listing 3 Version info from the Installer log
./System/Library/Extensions/AppleMesh.kext (version 1.1.0.1.1) was not installed because a newer version (1.1.0.1.60) already exists. |
./System/Library/Extensions/IOUSBFamily.kext/Contents/PlugIns/IOUSBLib.bundle (version 1.8.3.1.1) was not installed because a newer version (1.8.3.1.3) already exists. |
./System/Library/PrivateFrameworks/DiscRecording.framework (version 1.2.0.1.1) was not installed because a newer version (1.2.0.1.30) already exists. |
./System/Library/Extensions/AppleStorageDrivers.kext/Contents/PlugIns/LSI-FW-500.kext (version 1.1.0.1.2) was not installed because a newer version (1.1.0.1.3) already exists. |
./System/Library/Extensions/System.kext/Contents/PlugIns/IOSystemManagement.kext (version 1.1.0.8.1) was not installed because a newer version (1.1.0.8.15) already exists. |
./System/Library/Extensions/System.kext/Contents/PlugIns/IOADBFamily.kext (version 1.1.0.8.1) was not installed because a newer version (1.1.0.8.15) already exists. |
Given the output in the log and knowledge of how Installer computes version 5-tuples, you should be able to track down and correct any problems with the installation.
© 2003, 2006 Apple Computer, Inc. All Rights Reserved. (Last updated: 2006-07-24)