Preferences and Settings Programming Guide
Preferences and Settings Programming Guide
Programming Guide
Contents
2
Contents
3
Figures, Tables, and Listings
4
About Preferences and Settings
Preferences are pieces of information that you store persistently and use to configure your app. Apps often
expose preferences to users so that they can customize the appearance and behavior of the app. Most
preferences are stored locally using the Cocoa preferences system—known as the user defaults system. Apps
can also store preferences in a user’s iCloud account using the key-value store.
The user defaults system and key-value store are both designed for storing simple data types—strings, numbers,
dates, Boolean values, URLs, data objects, and so forth—in a property list. The use of a property list also means
you can organize your preference data using array and dictionary types. It is also possible to store other objects
in a property list by encoding them into an NSData object first.
At a Glance
Apps integrate preferences in several ways, including programmatically at various points throughout your
code and as part of the user interface. Preferences are supported in both iOS and Mac apps.
5
About Preferences and Settings
At a Glance
6
About Preferences and Settings
See Also
Note: Apps are not required to use a Settings bundle to manage all preferences. For preferences
that the user is likely to change frequently, the app can display its own custom interface for managing
those preferences.
See Also
For information about property lists, see Property List Programming Guide .
For more advanced information about using Core Foundation to manage preferences, see Preferences
Programming Topics for Core Foundation .
7
About the User Defaults System
The user defaults system manages the storage of preferences for each user. Most preferences are stored
persistently and therefore do not change between subsequent launch cycles of your app. Apps use preferences
to track user-initiated and program-initiated configuration changes.
Storing objects persistently means that your app has to decode that object at some point. In the case of
preferences, a stored object means decoding the object every time you access the preference. It also means
that a newer version of your app has to ensure that it is able to decode objects created and written to disk
using an earlier version of your app, which is potentially error prone.
A better approach for preferences is to store simple strings and values and use them to create the objects your
app needs. Storing simple values means that your app can always access the value. The only thing that changes
from release to release is the interpretation of the simple value and the objects your app creates in response.
Preference iOS OS X
8
About the User Defaults System
The Organization of Preferences
Note: An example of preferences that might change frequently include things like the volume levels
or control options of a game. An example of preferences that might change infrequently are the
email address and server settings in the Mail app. For iOS apps, it is ultimately up to you to decide
whether it is appropriate to expose preferences from the Settings app or from inside your app.
Preferences in Mac apps should be accessible from a Preferences menu item in the app menu. Cocoa apps
created using the Xcode templates provide such a menu item for you automatically. It is your responsibility to
present an appropriate user interface when the user chooses this menu item. You can provide that user interface
by defining an action method in your app delegate that displays a custom preferences window and connecting
that action method to the menu item in Interface Builder.
There is no standard way to display custom preferences from inside an iOS app. You can integrate preferences
in many ways, including using a separate tab in a tab-bar interface or using a custom button from one of your
app’s screens. Preferences should generally be presented using a distinct view controller so that changes in
preferences can be recorded when that view controller is dismissed by the user.
The lifetime of a preference depends on which domain you store it in. Some domains store preferences
persistently by writing them to the user’s defaults database. Such preferences continue to exist from one app
launch to the next. Other domains store preferences in a more volatile way, preserving preference values only
for the life of the corresponding user defaults object.
9
About the User Defaults System
The Organization of Preferences
A search for the value of a given preference proceeds through the domains in an NSUserDefaults object’s
search list. Only domains in the search list are searched and they are searched in the order shown in Table 1-2,
starting with the NSArgumentDomain domain. A search ends when a preference with the specified name is
found. If multiple domains contain the same preference, the value is taken from the domain nearest the
beginning of the search list.
Domain State
NSArgumentDomain volatile
NSGlobalDomain persistent
NSRegistrationDomain volatile
Preferences set from the command line temporarily override the established values stored in the user’s defaults
database. In the preceding example, setting the IndexOnOpen preference to NO prevents Xcode from indexing
projects automatically, even if the preference is set to YES in the user defaults database.
10
About the User Defaults System
The Organization of Preferences
Because this domain is app-specific, the contents of the domain are tied to your app’s bundle identifier. The
contents of this domain are stored in a file that is managed by the system. Currently, this file is located in the
$HOME /Library/Preferences/ directory, where $HOME is either the app’s home directory or the user’s
home directory (depending on the platform and whether your app is in a sandbox). The name of the user
defaults database file is <ApplicationBundleIdentifer> .plist, where <ApplicationBundleIdentifer> is your
app’s bundle identifier. You should not modify this file directly but can inspect it during debugging to make
sure preference values are being written by your app.
11
About the User Defaults System
Viewing Preferences Using the Defaults Tool
The contents of the registration domain can be set only by using the registerDefaults: method.
To read the contents of the global domain, you would use the following command:
For more information about using the defaults tool to read and write preference values, see defaults man
page.
12
Accessing Preference Values
You use the NSUserDefaults class to gain access to your app’s preferences. Each app is provided with a
single instance of this class, accessible from the standardUserDefaults class method. You use the shared
user defaults object to:
● Specify any default values for your app’s preferences at launch time.
● Get and set individual preference values stored in the app domain.
● Remove preference values.
● Examine the contents of the volatile preference domains.
Mac apps that use Cocoa bindings can use an NSUserDefaultsController object to set and get preferences
automatically. You typically add such an object to the same nib file you use for displaying user-facing preferences.
You bind your user interface controls to items in the user defaults controller, which handles the process of
getting and setting values in the user defaults database.
Preference values must be one of the standard property list object types: NSData, NSString, NSNumber,
NSDate, NSArray, or NSDictionary. The NSUserDefaults class also provides built-in manipulations for
storing NSURL objects as preference values. For more information about property lists and their contents, see
Property List Programming Guide .
When calling the registerDefaults: method, you must provide a dictionary of all the default values you
need to register. Listing 2-1 shows an example where an iOS app registers its default values early in the launch
cycle. You can register default values at any time, of course, but should always register them before attempting
to retrieve any preference values.
13
Accessing Preference Values
Getting and Setting Preference Values
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
dictionaryWithObject:[NSNumber numberWithBool:YES]
forKey:@"CacheDataAgressively"];
// Other initialization...
When registering default values for scalar types, use an NSNumber object to specify the value for the number.
If you want to register a preference whose value is a URL, use the archivedDataWithRootObject: method
of NSKeyedArchiver to encode the URL in an NSData object first. Although you can use a similar technique
for other types of objects, you should avoid doing so when a simpler option is available.
The following code shows how you might get a preference value in your code. In this example, the code
retrieves the value of the CacheDataAggressively key, which is custom key that the app might use to
determine its caching strategy. Code like this can be used anywhere to handle custom configuration of your
app. If you wanted to display this particular preference value to the user, you would use similar code to configure
the controls of your preferences interface.
14
Accessing Preference Values
Synchronizing and Detecting Preference Changes
To set a preference value programmatically, you call the corresponding setter methods of NSUserDefaults.
When setting object values, you must use the setObject:forKey: method. When calling this method, you
must make sure that the object is one of the standard property list types. The following example sets some
preferences based on the state of the app’s preferences interface.
} else {
[defaults removeObjectForKey:@"CacheExpirationDate"];
You do not have to display a preferences interface to manage all values. Your app can use preferences to cache
interesting information. For example, NSWindow objects store their current location in the user defaults system.
This data allows them to return to the same location the next time the user starts the app.
15
Accessing Preference Values
Managing Preferences Using Cocoa Bindings
To detect when changes to a preference value occur, apps can also register for the notification
NSUserDefaultsDidChangeNotification. The shared NSUserDefaults object sends this notification
to your app whenever it detects a change to a preference located in one of the persistent domains. You can
use this notification to respond to changes that might impact your user interface. For example, you could use
it to detect changes to the user’s preferred language and update your app content appropriately.
For more information on how to use the NSUserDefaultsController class to bind preference values to
your user interface, see “User Defaults and Bindings” in Cocoa Bindings Programming Topics .
For information about the Core Foundation functions for getting and setting preferences, see Preferences
Utilities Reference .
16
Accessing Preference Values
Managing Preferences Using Core Foundation
pixels of any new windows that your app creates. Its value would most likely be of type CFNumber. You might
also decide to combine window width and height into a single preference called defaultWindowSize and
make its value be a CFArray object containing two CFNumber objects.
The code in Listing 2-2 demonstrates how to create a simple preference for the app MyTextEditor. The example
sets the default text color for the app to blue.
CFPreferencesSetAppValue(textColorKey, colorBLUE,
kCFPreferencesCurrentApplication);
CFPreferencesAppSynchronize(kCFPreferencesCurrentApplication);
Notice that CFPreferencesSetAppValue by itself is not sufficient to create the new preference. A call to
CFPreferencesAppSynchronize is required to actually save the value. If you are writing multiple preferences,
it is more efficient to sync only once after the last value has been set than to sync after each individual value
is set. For example, if you implement a preference pane you might synchronize only when the user presses an
OK button. In other cases you might not want to sync at all until the app quits—although note that if the app
crashes, all unsaved preferences settings will be lost.
CFStringRef textColor;
17
Accessing Preference Values
Managing Preferences Using Core Foundation
textColor = (CFStringRef)CFPreferencesCopyAppValue(textColorKey,
kCFPreferencesCurrentApplication);
// CFRelease(textColor);
All values returned from preferences are immutable, even if you have just set the value using a mutable object.
18
Storing Preferences in iCloud
An app can use the iCloud key-value store to share small amounts of data with other instances of itself on the
user’s other computers and iOS devices. The key-value store is intended for simple data types like those you
might use for preferences. For example, a magazine app might store the current issue and page number being
read by the user so that other instances of the app can open to the same page when launched. You should
not use this store for large amounts of data or for complex data types.
Key-value data in iCloud is limited to simple property-list types (strings, numbers, dates, and so on).
19
Storing Preferences in iCloud
Configuring Your App to Use the Key-Value Store
● The key-value store is not a replacement for preferences or other local techniques for saving the same
data. The purpose of the key-value store is to share data between apps, but if iCloud is not enabled or is
not available on a given device, you still might want to keep a local copy of the data.
If you are using the key-value store to share preferences, one approach is to store the actual values in the user
defaults database and synchronize them using the key-value store. (If you do not want to use the preferences
system, you could also save the changes in a custom property-list file or some other local storage.) When you
change the value of a key locally, write that change to both the user defaults database and to the iCloud
key-value store at the same time. To receive changes from external sources, add an observer for the notification
NSUbiquitousKeyValueStoreDidChangeExternallyNotification and use your handler method to
detect which keys changed externally and update the corresponding data in the user defaults database. By
doing this, your user defaults database always contains the correct configuration values. The iCloud key-value
store simply becomes a mechanism for ensuring that the user defaults database has the most recent changes.
When you enable key-value store, Xcode automatically fills in a default value for the containers field that is
based on the bundle identifier of your app. For most apps, the default value is what you want. However, if your
app shares its key-value storage with another app, you must specify the bundle identifier for the other app
instead. For example, if you have a lite version of your app, you might want it to use the same key-value store
as the paid version.
Enabling the entitlement is all you have to do to use the shared NSUbiquitousKeyValueStore object. As
long as the entitlement is configured and contains a valid value, the key-value store object writes its data to
the appropriate location in the user’s iCloud account. If there is a problem attaching to the specified iCloud
container, any attempts to read or write key values will fail. To ensure the key-value store is configured properly
and accessible, you should execute code similar to the following early in your app’s launch cycle:
selector:@selector(updateKVStoreItems:)
name:NSUbiquitousKeyValueStoreDidChangeExternallyNotification
object:store];
20
Storing Preferences in iCloud
Accessing Values in the Key-Value Store
[store synchronize];
Creating the key-value store object early in your app’s launch cycle is recommended because it ensures that
your app receives updates from iCloud in a timely manner. The best way to determine if changes have been
made to keys and values is to register for the notification
NSUbiquitousKeyValueStoreDidChangeExternallyNotification. And at launch time, you should
call the synchronize method manually to detect if any changes were made externally. You do not need to
call that method at other times during you app’s execution.
For more information about how to configure entitlements for an iOS app, see “Adding Capabilities” in App
Distribution Guide .
If you are using the key-value store as a way to update locally stored preferences, you could use code similar
to that in Listing 3-1 to coordinate updates to the user defaults database. This example assumes that you use
the same key names and corresponding values in both iCloud and the user defaults database. It also assumes
that you previously registered the updateKVStoreItems: method as the method to call in response to the
notification NSUbiquitousKeyValueStoreDidChangeExternallyNotification.
- (void)updateKVStoreItems:(NSNotification*)notification {
if (!reasonForChange)
return;
21
Storing Preferences in iCloud
Defining the Scope of Key-Value Store Changes
if ((reason == NSUbiquitousKeyValueStoreServerChange) ||
(reason == NSUbiquitousKeyValueStoreInitialSyncChange)) {
// This loop assumes you are using the same key names in both
If you have a group of keys whose values must all be updated at the same time in order to be valid, save them
together in a single transaction. To write multiple keys and values in a single transaction, create an
NSDictionary object with all of the keys and values. Then write the dictionary object to the key-value store
using the setDictionary:forKey: method. Writing an entire dictionary of changes ensures that all of the
keys are written or none of them are.
22
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:
● Display preferences inside the app.
● Use a Settings bundle to manage preferences from the Settings app.
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 .
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.
23
Implementing an iOS Settings Bundle
The Settings App Interface
Controltype 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 The toggle switch type displays an ON/OFF toggle button. You can use this type to
switch 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” (page 26).
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” (page
28).
24
Implementing an iOS Settings Bundle
The Settings Bundle
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” (page 26).
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 These directories store localized string resources for your Settings page files.
directories 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 iOS App Programming Guide .
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.
25
Implementing an iOS Settings Bundle
The Settings Bundle
Note: Xcode converts any XML-based property files in your project to binary format when building
your app. This conversion saves space and is done for you automatically.
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.
PreferenceSpecifiers Array The value for this key is an array of dictionaries, with each
(required) dictionary containing the information for a single control.
For a list of control types, see Table 4-1 (page 24). 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” (page 27).
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
26
Implementing an iOS Settings Bundle
The Settings Bundle
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.
General page
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.
27
Implementing an iOS Settings Bundle
Creating and Modifying the Settings Bundle
For information about the format of strings files, language-specific project directories, and how language-specific
resources are retrieved from bundles, see Internationalization Programming Topics .
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.
Settings.bundle/
Root.plist
en.lproj/
Root.strings
28
Implementing an iOS Settings Bundle
Creating and Modifying the Settings Bundle
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.
29
Implementing an iOS Settings Bundle
Creating and Modifying the Settings Bundle
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.
30
Implementing an iOS Settings Bundle
Creating and Modifying the Settings Bundle
31
Implementing an iOS Settings Bundle
Creating and Modifying the 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” (page 30). To display the settings for your page, you must reference
it from a child pane control as described in “Hierarchical Preferences” (page 26).
32
Implementing an iOS Settings Bundle
Debugging Preferences for Simulated Apps
Note: In Xcode 4, adding a property-list file to your project does not automatically associate it with
your Settings bundle. You must use the Finder to move any additional property-list files into your
Settings bundle.
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.
33
Document Revision History
This table describes the changes to Preferences and Settings Programming Guide .
Date Notes
2012-03-01 Updated the document to reflect new limits for key and value sizes.
Removed the articles on storing NSColor objects and using Cocoa bindings
and now link to their locations instead.
2006-09-05 Made small additions to the content. Changed title from "User Defaults."
34
Document Revision History
Date Notes
2002-11-12 Revision history was added to existing topic. It will be used to record
changes to the content of the topic.
35
Apple Inc.
Copyright © 2013 Apple Inc.
All rights reserved.