Dev:Preferences specifier plist

This document provides the specification of the .plist file that specifies the layout of an iPhone preference pane.

Root level
The root level of the plist may contain these keys:

"struct &lt;preferences specifier plist&gt; ::"

Localization
Some strings, e.g. the title of the preference pane is localizable. Preferences.framework can localize these strings by looking for the corresponding key in localizationTable.strings in bundle. If you are writing a PreferenceBundles, the localizationTable is the name of the specifier plist and bundle is of course the PreferenceBundle itself.

For example, if the plist is named MySettings.plist, then the corresponding strings file should be named MySettings.strings.

Specifier Entries
You can use any keys that your controller recognizes in the plist for further customization. This table lists the internal ones:

"struct &lt;entry&gt; ::"

General keys
Here, cell must be one of: The cell type is actually determined from the class method.
 * enum &lt;cell type&gt; ::
 * PSGroupCell
 * PSLinkCell
 * PSLinkListCell
 * PSListItemCell
 * PSTitleValueCell
 * PSSliderCell
 * PSSwitchCell
 * PSStaticTextCell
 * PSEditTextCell
 * PSSegmentCell
 * PSGiantIconCell
 * PSGiantCell
 * PSSecureEditTextCell
 * PSButtonCell
 * PSEditTextViewCell
 * PSSpinnerCell

bundle-dependent keys
The following keys are meaningful when bundle is present. It is useful for loading extra resources and custom code.

get, set and action should respectively have signatures where the type of "something" depends on the type of specifier, e.g. for a text field it should be an NSString, while for a switch it should be an NSNumber with boolean.

Of course, you can ignore extra parameters, e.g. -(void)specifierPerformedAction is a valid signature too.

Editing cells
These keys are specific to editing cells.

List cells
These keys are specific to list cells.

valuesDataSource and titlesDataSource are performed on the target sent from. They must return an NSArray containing the values and (localized) titles respectively. Their signatures should be

Slider and switch cells
These keys are specific to slider and switch cells.

Miscellaneous control cells
These keys are specific to other control cells.

footerAlignment: 1 centers the footer text (doesn't always look good for multiple lines)

Here, confirmation itself is a dictionary containing the following fields:

"struct &lt;confirmation&gt; ::"

PSSpecifier</tt> properties of plist keys
The tables above only shows the keys recognized by SpecifiersForPlist</tt> when translating the plist into an array of PSSpecifier</tt>s. They may be corresponds to the actual properties of the specifier. If you would like to generate a PSSpecifier</tt> in runtime, some actions may differ:

Using PSLinkListCell
In order to make a PSLinkListCell actually work like a list, you must supply the key-value pair detail = "PSListItemsController"; also.

Using PSSpinnerCell
PSSpinnerCell is a simple cell with an animating spinner (UIActivityIndicatorView) inside it. Available only in iOS 7. (or higher) There is no way to start or stop the animation manually, it is always running. Therefore, this cell is meant to be dynamically inserted and deleted from a PSListController subclass. PSSpinnerCell supports text and icons as well.

Using PSLinkCell
PSLinkCell is useful for linking to sub-preference-panes. The simplest example just needs 2 keys: { cell = PSLinkCell; label = "Settings-iPhone"; } The label is the important part. When user clicked on the link cell, iPhoneOS will use the unlocalized label as the file name of the plist for the next pane. For example in above, the main settings screen will appear.

If you use just 2 keys, only plists inside can be loaded. In order to load your own plist, you must use a custom subclass of PSListController in detail: { cell  = PSLinkCell; label = "My Awesome Pane"; detail = MyListController; } MyListController can simply be an empty subclass of PSListController: The key thing is when you place MyListController inside your bundle, its bundle property will return your bundle which My Awesome Pane.plist</tt> can be found.

Constructing a PSLinkCell at runtime
If you want to dynamically add a specifier for a PSLinkCell linking to a bundle, do it like this:

Making a red delete button
The red delete button in VPN is in fact very easy to implement. All you need to do is add the following code:

and then in the specifier plist, modify your button as: ... { cell = PSButtonCell; action = nukeFromOrbit; label = "Nuke from Orbit"; ...  cellClass = PSDeleteTableCell; }, ...

Note that  no longer exists as of iOS 6.0. It appears to be replaced by a boolean on PSButtonCell,.

Making a custom cell, header or footer
Making a custom cell, header or footer is useful because it allows you to customize the style, add an image, etc.

All you need to do is make a class that looks like: Then, set the,   or   in your specifier. For example: ... {   cell = PSGroupCell; footerCellClass = CustomCell; }, ... A  doesn't have to be specified for custom cells.

Making an editable PSListController
Making a PSListController editable, so you can preform "swipe-to-delete" on the rows is easy at runtime.

You just have to use a subclass of  (which is a subclass of   ) instead of a subclass of   for your List Controller. For example:

Please note, you will only be able to delete a specifier, if it's class is either,   or

To perform a custom action when the specifier gets deleted, you have to implent a method in your PSEditableListController subclass like this one

and set the deletionAction Key of the specifier: