Implementing an iOS Settings Bundle

In iOS, the Foundation framework provides the low-level mechanism for storing the preference data. Apps then have two options for presenting preferences:

Which option you choose depends on how you expect users to interact with preferences. The Settings bundle is generally the preferred mechanism for displaying preferences. However, games and other apps that contain configuration options or other frequently accessed preferences might want to present them inside the app instead. Regardless of how you present them, you use the NSUserDefaults class to access preference values from your code.

This chapter focuses on the creation of a Settings bundle for your app. A Settings bundle contains files that describe the structure and presentation style of your preferences. The Settings app uses this information to create an entry for your app and to display your custom preference pages.

For guidelines on how to manage and present settings and configuration options, see iOS Human Interface Guidelines.

The Settings App Interface

The Settings app implements a hierarchical set of pages for navigating app preferences. The main page of the Settings app lists the system and third-party apps whose preferences can be customized. Selecting a third-party app takes the user to the preferences for that app.

Every app with a Settings bundle has at least one page of preferences, referred to as the main page. If your app has only a few preferences, the main page may be the only one you need. If the number of preferences gets too large to fit on the main page, however, you can create child pages that link off the main page or other child pages. There is no specific limit to the number of child pages you can create, but you should strive to keep your preferences as simple and easy to navigate as possible.

The contents of each page consists of one or more controls that you configure. Table 4-1 lists the types of controls supported by the Settings app and describes how you might use each type. The table also lists the raw key name stored in the configuration files of your Settings bundle.

Table 4-1  Preference control types

Control type

Description

Text field

The text field type displays a title (optional) and an editable text field. You can use this type for preferences that require the user to specify a custom string value.

The key for this type is PSTextFieldSpecifier.

Title

The title type displays a read-only string value. You can use this type to display read-only preference values. (If the preference contains cryptic or nonintuitive values, this type lets you map the possible values to custom strings.)

The key for this type is PSTitleValueSpecifier.

Toggle switch

The toggle switch type displays an ON/OFF toggle button. You can use this type to configure a preference that can have only one of two values. Although you typically use this type to represent preferences containing Boolean values, you can also use it with preferences containing non-Boolean values.

The key for this type is PSToggleSwitchSpecifier.

Slider

The slider type displays a slider control. You can use this type for a preference that represents a range of values. The value for this type is a real number whose minimum and maximum value you specify.

The key for this type is PSSliderSpecifier.

Multivalue

The multivalue type lets the user select one value from a list of values. You can use this type for a preference that supports a set of mutually exclusive values. The values can be of any type.

The key for this type is PSMultiValueSpecifier.

Group

The group type is for organizing groups of preferences on a single page. The group type does not represent a configurable preference. It simply contains a title string that is displayed immediately before one or more configurable preferences.

The key for this type is PSGroupSpecifier.

Child pane

The child pane type lets the user navigate to a new page of preferences. You use this type to implement hierarchical preferences. For more information on how you configure and use this preference type, see Hierarchical Preferences.

The key for this type is PSChildPaneSpecifier.

For detailed information about the format of each preference type, see Settings Application Schema Reference. To learn how to create and edit Settings page files, see Creating and Modifying the Settings Bundle.

The Settings Bundle

A Settings bundle has the name Settings.bundle and resides in the top-level directory of your app’s bundle. This bundle contains one or more Settings page files that describe the individual pages of preferences. It may also include other support files needed to display your preferences, such as images or localized strings. Table 4-2 lists the contents of a typical Settings bundle.

Table 4-2  Contents of the Settings.bundle directory

Item name

Description

Root.plist

The Settings page file containing the preferences for the root page. The name of this file must be Root.plist. The contents of this file are described in more detail in The Settings Page File Format.

Additional .plist files

If you build a set of hierarchical preferences using child panes, the contents for each child pane are stored in a separate Settings page file. You are responsible for naming these files and associating them with the correct child pane.

One or more .lproj directories

These directories store localized string resources for your Settings page files. Each directory contains a single strings file, whose title is specified in your Settings page file. The strings files provide the localized strings to display for your preferences.

Additional images

If you use the slider control, you can store the images for your slider in the top-level directory of the bundle.

In addition to the Settings bundle, the app bundle can contain a custom icon for your app settings. The Settings app displays the icon you provide next to the entry for your app preferences. For information about app icons and how you specify them, see App Programming Guide for iOS.

When the Settings app launches, it checks each custom app for the presence of a Settings bundle. For each custom bundle it finds, it loads that bundle and displays the corresponding app’s name and icon in the Settings main page. When the user taps the row belonging to your app, Settings loads the Root.plist Settings page file for your Settings bundle and uses that file to build your app’s main page of preferences.

In addition to loading your bundle’s Root.plist Settings page file, the Settings app also loads any language-specific resources for that file, as needed. Each Settings page file can have an associated .strings file containing localized values for any user-visible strings. As it prepares your preferences for display, the Settings app looks for string resources in the user’s preferred language and substitutes them in your preferences page prior to display.

The Settings Page File Format

Each Settings page file is stored in the iPhone Settings property-list file format, which is a structured file format. The simplest way to edit Settings page files is to use the built-in editor facilities of Xcode; see Preparing the Settings Page for Editing. You can also edit property-list files using the Property List Editor app that comes with the Xcode tools.

The root element of each Settings page file contains the keys listed in Table 4-3. Only one key is actually required, but it is recommended that you include both of them.

Table 4-3  Root-level keys of a preferences Settings page file

Key

Type

Value

PreferenceSpecifiers (required)

Array

The value for this key is an array of dictionaries, with each dictionary containing the information for a single control. For a list of control types, see Table 4-1. For a description of the keys associated with each control, see Settings Application Schema Reference.

StringsTable

String

The name of the strings file associated with this file. A copy of this file (with appropriate localized strings) should be located in each of your bundle’s language-specific project directories. If you do not include this key, the strings in this file are not localized. For information on how these strings are used, see Localized Resources.

Hierarchical Preferences

If you plan to organize your preferences hierarchically, each page you define must have its own separate .plist file. Each .plist file contains the set of preferences displayed only on that page. Your app’s main preferences page is always stored in a file called Root.plist. Additional pages can be given any name you like.

To specify a link between a parent page and a child page, you include a child pane control in the parent page. A child pane control creates a row that, when tapped, displays a new page of settings. The File key of the child pane control identifies the name of the .plist file with the contents of the child page. The Title key identifies the title of the child page; this title is also used as the text of the control used to display the child page. The Settings app automatically provides navigation controls on the child page to allow the user to navigate back to the parent page.

Figure 4-1 shows how this hierarchical set of pages works. The left side of the figure shows the .plist files, and the right side shows the relationships between the corresponding pages.

Figure 4-1  Organizing preferences using child panes
Organizing preferences using child panes

For more information about child pane controls and their associated keys, see Settings Application Schema Reference.

Localized Resources

Because preferences contain user-visible strings, you should provide localized versions of those strings with your Settings bundle. Each page of preferences can have an associated .strings file for each localization supported by your bundle. When the Settings app encounters a key that supports localization, it checks the appropriately localized .strings file for a matching key. If it finds one, it displays the value associated with that key.

When looking for localized resources such as .strings files, the Settings app follows the same rules that other iOS apps follow. It first tries to find a localized version of the resource that matches the user’s preferred language setting. If no such resource exists, an appropriate fallback language is selected.

For information about the format of strings files, language-specific project directories, and how language-specific resources are retrieved from bundles, see Internationalization and Localization Guide.

Creating and Modifying the Settings Bundle

Xcode provides a template for adding a Settings bundle to your current project. The default Settings bundle contains a Root.plist file and a default language directory for storing any localized resources. You can expand this bundle as needed to include additional property list files and resources needed by your Settings bundle.

Adding the Settings Bundle

To add a Settings bundle to your Xcode project:

  1. Choose File > New > New File.

  2. Under iOS, choose Resource, and then select the Settings Bundle template.

  3. Name the file Settings.bundle.

In addition to adding a new Settings bundle to your project, Xcode automatically adds that bundle to the Copy Bundle Resources build phase of your app target. Thus, all you have to do is modify the property list files of your Settings bundle and add any needed resources.

The new Settings bundle has the following structure:

Settings.bundle/
    Root.plist
    en.lproj/
        Root.strings

Preparing the Settings Page for Editing

Before editing any of the property-list files in your Settings bundle, you should configure the Xcode editor to format the contents of those files as iPhone settings. Xcode does this automatically for the Root.plist file, but you may need to format additional property-list files manually. To format a file as iPhone Settings, do the following:

  1. Select the file.

  2. Control-click the editor window and choose Property List Type > iPhone Settings plist if it is not already chosen.

    Formatting a property list makes it easier to understand and edit the file’s contents. Xcode substitutes human-readable strings (as shown in Figure 4-2) that are appropriate for the selected format.

    Figure 4-2  Formatted contents of the Root.plist file
    Formatted contents of the Root.plist fileFormatted contents of the Root.plist file

Configuring a Settings Page: A Tutorial

This section shows you how to configure a Settings page to display the controls you want. The goal of the tutorial is to create a page like the one in Figure 4-3. If you have not yet created a Settings bundle for your project, you should do so as described in Adding the Settings Bundle before proceeding with these steps.

Figure 4-3  A root Settings page
A root Settings page
  1. Disclose the Preference Items key to display the default items that come with the template.

  2. Change the title of Item 0 to Sound.

    • Disclose Item 0 of Preference Items.

    • Change the value of the Title key from Group to Sound.

    • Leave the Type key set to Group.

    • Click the disclosure triangle of the item to hide its contents.

  3. Create the first toggle switch for the renamed Sound group.

    • Select Item 2 (the toggle switch item) of Preference Items and choose Edit > Cut.

    • Select Item 0 and choose Edit > Paste. (This moves the toggle switch item in front of the text field item.)

    • Disclose the toggle switch item to reveal its configuration keys.

    • Change the value of the Title key to Play Sounds.

    • Change the value of the Identifier key to play_sounds_preference.

    • Click the disclosure triangle of the item to hide its contents.

  4. Create a second toggle switch for the Sound group.

    • Select Item 1 (the Play Sounds toggle switch).

    • Choose Edit > Copy.

    • Choose Edit >Paste to place a copy of the toggle switch right after the first one.

    • Disclose the new toggle switch item to reveal its configuration keys.

    • Change the value of its Title key to 3D Sound.

    • Change the value of its Identifier key to 3D_sound_preference.

    • Click the disclosure triangle of the item to hide its contents.

    At this point, you have finished the first group of settings and are ready to create the User Info group.

  5. Change Item 3 into a Group control and name it User Info.

    • Click Item 3 in the Preferences Items. This displays a pop-up menu with a list of item types.

    • From the pop-up menu, choose Group to change the type of the control.

    • Disclose the contents of Item 3.

    • Set the value of the Title key to User Info.

    • Click the disclosure triangle of the item to hide its contents.

  6. Create the Name field.

    • Select Item 4 in the Preferences Items.

    • Using the pop-up menu, change its type to Text Field.

    • Set the value of the Title key to Name.

    • Set the value of the Identifier key to user_name.

    • Click the disclosure triangle of the item to hide its contents.

  7. Create the Experience Level settings.

    • Select Item 4.

    • Control-click the editor window and select Add Row to add a new item.

    • Set the type of the new item to Multi Value.

    • Disclose the item’s contents and set its title to Experience Level, its identifier to experience_preference, and its default value to 0.

    • With the Default Value key selected, Control-click and select Add Row to add a Titles array.

    • Select the Titles array and press Return to add a new subitem.

    • Add two more subitems to create a total of three items.

    • Set the values of the subitems to Beginner, Expert, and Master.

    • Hide the key’s subitems.

    • Add a new item for the Values array.

    • Add three subitems to the Values array and set their values to 0, 1, and 2.

    • Hide the contents of Item 5.

  8. Add the final group to your settings page.

    • Create a new item and set its type to Group and its title to Gravity.

    • Create another new item and set its type to Slider, its identifier to gravity_preference, its default value to 1, and its maximum value to 2.

Creating Additional Settings Page Files

The Settings Bundle template includes the Root.plist file, which defines your app’s top Settings page. To define additional Settings pages, you must add additional property list files to your Settings bundle.

To add a property list file to your Settings bundle in Xcode, do the following:

  1. Choose File > New > New File.

  2. Under iOS, select Resource, and then select the Property List template.

  3. Select the new file to display its contents in the editor.

  4. Control-click the editor pane and choose Property List Type > iPhone Settings plist to format the contents.

  5. Control-click the editor pane again and choose Add Row to add a new key.

  6. Add and configure any additional keys you need.

After adding a new Settings page to your Settings bundle, you can edit the page’s contents as described in Configuring a Settings Page: A Tutorial. To display the settings for your page, you must reference it from a child pane control as described in Hierarchical Preferences.

Debugging Preferences for Simulated Apps

When running your app, iOS Simulator stores any preferences values for your app in ~/Library/Application Support/iOS Simulator/User/Applications/<APP_ID>/Library/Preferences, where <APP_ID> is a programmatically generated directory name that iOS uses to identify your app.

Each time you build your app, Xcode preserves your app preferences and other relevant library files. If you want to remove the current preferences for testing purposes, you can delete the app from Simulator or choose Reset Contents and Settings from the iOS Simulator menu.