Preferences: Property lists and their use

Standard preference files are written in XML format according to the definitions of a property list, which you’ll also encounter in other important places, including:

  • the Info.plist file required in every app and bundle,
  • LaunchAgents and LaunchDaemons files, responsible for configuring most services,
  • many configuration files throughout the system,
  • system records like software installation receipts, and the InstallHistory.

Although normally considered to be in plain UTF-8 text format, macOS stores many of these in a more compact binary format. Their contents are structured into dictionaries <dict> and arrays <array>. Dictionaries contain key-value pairs like
<key>AppleLocale</key>
<string>en_GB</string>

to set the value of AppleLocale to the text string en_GB. Values can themselves be arrays or dictionaries, and it’s common for property lists to run several layers deep in that way. There’s a limited range of value types defined in the PLIST 1.0 definition, so it’s usual for many numbers to be saved as string values, which then have to be converted back to their original datatype when the property list is accessed.

proplist1

Property lists all start with the same three lines defining their type as a property list according to Apple’s reference specification and version. Following those are the contents, normally in a top-level dictionary, in the case of preference files. Key-value pairs are usually arranged in a set order, with those used by the API, whose keys might start with NS as in NSWindow, at the top, followed by the custom keys containing the app’s own internal settings, such as checkInfoout. The latter keys are named by the developer in accordance with their source code, and can be more or less informative.

proplist2

The values shown here illustrate some of the more common in use, including strings of text, Boolean true or false, and integers. Note, though, how the numeric dimensions of NSWindow Frames are given as strings containing integers, rather than integer values themselves.

proplist4

In this case, the contents are structured in a more complex way. This property list contains a dictionary of three arrays, each with its own key. The first two are folded away in the text editor (BBEdit), and the third is fully opened out to view. Within the value for the key specStyleList is an array of arrays, each consisting of a pair of strings, the first containing a text label, and the second the string of formatting codes associated with that label. These aren’t designed or formatted for humans to read, but are readily read and written by code.

While you can edit many property lists directly, preferences are managed by the cfprefsd service, and great care must be taken when changing them, or the changes may be overwritten by cfprefsd. The standard command tool for working with preferences is defaults. To demonstrate how this works, I edited an old preference file for Consolation 2. First I added a new key-value pair using the command
defaults write co.eclecticlight.Consolation2 extraSetting "Only a test"
to add the string value Only a test for the key extraSetting. That was quickly reflected in the property list as

proplist5

I confirmed that with the command
defaults read co.eclecticlight.Consolation2 extraSetting
to return the string value for the key extraSetting as Only a test.

In most cases, adding a new key-value pair will have no effect on the app, as it simply won’t look for them. However, to be safe and return that preference file to its original state, I deleted that extra key-value pair with the command
defaults delete co.eclecticlight.Consolation2 extraSetting

As an alternative to using the defaults command, you can instead use Prefs Editor. When working with more complex property lists, this is often more straightforward. First you select the app ID whose preference file you want to edit.

proplist6

Prefs Editor then opens its property list in a proper GUI editor, making it easy to change values for any of the keys. When you do make changes, they are immediately passed to cfprefsd to cast into the preference file without any risk of conflict or overwriting.

proplist7

With defaults and Prefs Editor, editing preference files becomes reliable and robust. There are two remaining problems, though:

  • Some values you’ll come across aren’t easy to manage. For example, links to files are often not made using their path given as a string, but instead using an encoded Bookmark, a close relative of the Finder Alias. You can use my free utility Precize to generate those if you need.
  • Although the key may give you a clue as to what that particular setting does, hardly any apps come with their preference files documented. Sometimes it’s a matter of trial and error.

Finally, if you want to change system settings, you also have to know where they are among the dozens if not hundreds of preference files that macOS uses.