Since the data represented by property lists is somewhat
abstract, the underlying
file format can be implemented in many ways. Namely,
NeXTSTEP used one format to represent a property list, and the subsequent
GNUstep and
macOS frameworks introduced differing formats.
NeXTSTEP Under
NeXTSTEP, property lists were designed to be
human-readable and edited by hand, serialized to
ASCII in a syntax somewhat like a
programming language. This same format was used by
OPENSTEP. • Strings are represented in C literal style: ; simpler, unquoted strings are allowed as long as they consist of alphanumericals and one of . • Binary data are represented as: <
[hexadecimal codes in ASCII] >. Spaces and comments between paired hex-codes are ignored. •
Arrays are represented as: . Trailing commas are tolerated. •
Dictionaries are represented as: {{code|1= { "key" = "value"; ... } }}. The left-hand side must be a string, but it can be unquoted. • Comments are allowed as: and . • As in C, whitespace are generally insignificant to syntax. Value statements terminate by a semicolon. One limitation of the original NeXT property list format is that it could not represent an NSValue (number, Boolean, etc.) object. As a result, these values would have to be converted to string, and "fuzzily" recovered by the application. The
defaults utility, introduced in OPENSTEP (1996), can be used to manipulate plist files used for storage of preferences (known as
defaults in NeXTSTEP, hence the name) on the command line via their preferences domain, and this utility can be used to edit arbitrary plist files. This utility superseded three older commands (dread, dwrite, and dremove). Binary data can also use the more efficient
base64 format as . The 8-bit problem is implicitly solved as well, as most deployments use UTF-8. GNUstep also has its own binary format, , implemented in . This format is defined recursively like the textual formats, with a single-byte type marker preceding some data. A form of
string interning is supported via a GS-extension switch. Two relative independent plist handlers are found in GNUstep: the in (CoreFoundation), and the in (Foundation Kit). Both support the binary and XML forms used by macOS to some degree, but the latter is a lot more complete. For example, the two GNUstep-specific formats are only handled in the latter. GNUstep provides a set of plist command-line tools based on , including a version of and .
macOS While macOS can also read the NeXTSTEP format, Apple sets it aside in favor of two new formats of its own, one XML-based and the other binary. Apple also has a partially-compatible JSON format ().
History In
Mac OS X 10.0, the NeXTSTEP format was
deprecated, and a new
XML format was introduced, with a public
DTD defined by
Apple. The XML format supports non-ASCII characters and storing NSValue objects (which, unlike GNUstep's ASCII property list format, Apple's ASCII property list format does not support). Since XML files, however, are not the most space-efficient means of storage,
Mac OS X 10.2 introduced a new format where property list files are stored as binary files. Starting with
Mac OS X 10.4, this is the default format for preference files. In
Mac OS X 10.7, support for reading and writing files in
JSON format was introduced. JSON and property lists are not fully compatible with each other, though. For example, property lists have native date and data types, which the JSON format does not support. Conversely, JSON permits null values while property lists do not support explicit nulls.
Tooling The old tool from NeXTSTEP remains available. The command provides an interactive plist editor. It can also be scripted. The utility (introduced in
Mac OS X 10.2) can be used to check the syntax of property lists, or convert a property list file from one format to another. It also supports converting plists to Objective-C or Swift object literals. Like the Cocoa it is built on, it takes "old-style" inputs, but does not convert to this type. (The Cocoa from before Mac OS X 10.2 emits old-styled output.) The utility is introduced in Mac OS X v10.5. It takes any input and tries to generate "old-style" plists. Like the GNUstep version, it appears to use the property of Foundation types found in plists, which Apple has specified to produce valid old-style plists. In terms of the internals, Apple provides an open source parser for old style, XML, and binary formats in their C
Core Foundation code as CFPropertyList. However, all the utilities and most parts of the system use the closed-source NSPropertyList parser from the Obj-C Foundation Kit. The Swift reimplementation is open source, but is not guaranteed to be identical.
Format XML and
JSON property lists are hand-editable in any text editor. Additionally, Apple provides support in
Xcode for editing property lists in a hierarchical viewer/editor that can handle plists formatted in binary or
XML, but not
JSON. As of
Mac OS X 10.4, Apple provides an
AppleScript interface for reading property list files through the System Events application. As of
Mac OS X 10.5, Apple provides an
AppleScript interface for editing, creating and writing property list files as well. For the XML format, the tags, related Foundation classes and CoreFoundation types, and data storage formats are as follows: The
binary file format is documented in a comment block in the
Core Foundation C code source file () for Apple's open sourced implementation of binary plists in its Foundation library. Apple describes the implementation as opaque in its plist(5) manual page documentation, which means that reliance on the format is discouraged. In the binary file format the magic number (the first few bytes of the file which indicate that it's a valid plist file) is the text
bplist, followed by two bytes indicating the version of the format. The binary file can store some information that cannot be captured in the XML or JSON file formats. The array, set and dictionary binary types are made up of
pointers - the objref and keyref entries - that index into an object table in the file. This means that binary plists can capture the fact that - for example - a separate array and dictionary serialized into a file both have the same data element stored in them. This cannot be captured in an XML file. Converting such a binary file will result in a copy of the data element being placed into the XML file. Additionally the binary file has a UID type that is used to identify data items when serialized. The complete list of data that can be stored taken from the C code source file is as follows: Note the note in many types. This means that the marker byte is only found in files with a format version no lower than the "1?" magic number. The precise way to parse them is more nebulous than the way to parse legacy types, since the CFBinaryPlist implementation only handles version "0?". In practice, these types are never encountered, since NSKeyedArchiver is already capable of capturing these information. A table of offsets follow the object table, which is then followed by a trailer containing information on the size and location of the two tables. == Serializing to plist ==