Some time ago, we had a useful discussion here about how to determine the version number of an app. This might appear obvious and uninteresting, but turns out to be more complex than meets the eye or Finder. In the course of doing something else more recently, I have been analysing the Information Property List (Info.plist) files for all apps and other bundles in Mojave. It turns out that what Apple requires isn’t what it does, and there isn’t any general way to determine the version number of an app or other bundle in macOS at all.
As with all other informative and useful documentation, Apple’s most coherent account has now been archived and isn’t being maintained. However, more limited documentation is provided within Xcode, and I’ll here refer to that.
Like all property lists, the Info.plist file consists of a dictionary of values for different keys. There are two different version keys which Apple gives as “recommended keys for Cocoa Apps”: CFBundleShortVersionString and CFBundleVersion. Another important key which I will mention later is NSHumanReadableCopyright.
CFBundleShortVersionString contains the text value which is normally displayed as the version number in the Finder. Apple’s current description of this amounts to:
This key is a user-visible string composed of three period-separated integers greater than zero, such as 10.14.1. The first integer represents a major revision, the second a minor revision, and the third a maintenance release.
This key is used throughout the system to identify the version of your app. The key is shown in the App Store and must match the store version number you enter in App Store Connect.
When you build an app in Xcode, it is this which is specified as the Version there.
CFBundleVersion is quite a different text value, which can be displayed in parentheses after the CFBundleShortVersionString. The current description reads:
This key is a machine-readable string composed of three period-separated integers greater than zero, such as 10.14.1. The string can only contain numeric characters (0-9) and periods. The first integer represents a major revision and can be up to four digits. The second represents a minor revision and can be up to two digits. The third represents a maintenance release and can be up to two digits.
This key is used throughout the system to identify your app’s build. Increment this version number before you distribute a build or upload it to App Store Connect.
When you build an app in Xcode, it is this which is specified as the Build there.
For NSHumanReadableCopyright, Apple writes tersely:
A human-readable copyright notice for the bundle.
This is also among the metadata which is normally shown in the Finder. This replaced CFBundleGetInfoString, which was used for this purpose until the autumn/fall of 2009, when it was made obsolete.
So let’s say I was about to release what I consider to be version 3.2r1 of my app. If I wanted the version to appear like that to the user, I’d set CFBundleShortVersionString to “3.2r1”. But for CFBundleVersion, I have to stick rigorously to an i.j.k scheme, so that would become “3.2.1”. And my NSHumanReadableCopyright might go something like “Copyright © 2019 The Eclectic Light Company. All rights reserved.”
I found 52 Apple apps in my main Applications folder (excluding Utilities). Of those, one had no CFBundleVersion value at all, and another gave a value of 1 which is plainly incorrect, as the CFBundleShortVersionString is given as 3.0. Of the other apps which do try to give a meaningful CFBundleVersion, only 6 gave a value which complies with the prescribed i.j.k scheme. So only around 10% of Apple’s apps meet its own stated requirements for CFBundleVersion.
Is CFBundleVersion any more meaningful than CFBundleShortVersionString in terms of differentiating versions of an app, though? In 6 apps, the two are identical, so in those there doesn’t appear to be any point in giving both. But in around 85% of Apple’s own apps, the two versions given are different and both appear to have some meaning at least.
Perhaps the most surprising discovery in this exploration of property lists is how few of Apple’s own apps contain an NSHumanReadableCopyright value: of those 52 apps, that key was unused in 21, or 40%. For most of those, copyright information is still given in the old CFBundleGetInfoString which was made obsolete almost ten years ago, in Snow Leopard.
If Apple can’t get its own Info.plist files conformant and up to date, then what should be expect of third-party developers?
The answer to my original question seems to be app-specific. How helpful.