Chapter 14
Application Settings

Key Skills & Concepts

• Creating a settings bundle

• Understanding settings field types

• Initializing an application with a settings bundle’s values

You adjust the settings for your iOS device through the Settings application (Figure 14-1). For instance, you can set your device’s brightness, Wi-Fi settings, and wallpaper settings using the Settings application. Different applications can also use the Settings application for setting their own configuration preferences. In this chapter, you learn how to add an application’s settings to the Settings application.

Image

Figure 14-1 The iOS Settings application

The Settings Application

The Settings application is used for setting both a device’s preferences and preferences for different applications. When using the Settings application for an application’s preferences, use it only for an application’s configuration settings and not for settings that change frequently. It will be much more convenient for your users if they change volatile preferences through the application’s interface rather than the Settings application.

The Settings Bundle

An application’s preferences are stored in an Extended Markup Language (XML) file called Root.plist. Root.plist is stored in a bundle called Settings.bundle. A settings bundle is not automatically added to your project, and so you must add it to your application if you want to use the Settings application (Figure 14-2). In addition to Root.plist, a settings bundle can contain any additional .plist files, any images used for sliders, and one or more .lproj files. Additional .plist files are for any child preference panes your application might require. The .lproj files are for localized string resources (not covered in this chapter). You can also store 16 × 16 pixel images you might want to use as the minimumImage and maximumImage on a slider pane in your preference panes.

Image

Figure 14-2 Adding a settings bundle

NOTE
You can also specify an icon for your application in the Settings application. Create a 29 × 29 pixel Portable Network Graphics (PNG) image and name it Icon-Settings.png. This file should be placed in your Xcode project’s Resources folder in Groups & Files.

Try This
Creating a Settings Bundle

1. Create a new View-based Application named MySettings.

2. Expand the Resources folder and add a new resource file of type Settings Bundle. Accept the default name. Select the Resources group as the place to add the Settings.bundle.

3. Expand Settings.bundle and click Root.plist (Figure 14-2). (You may need to display the Utilities pane and change the type of Settings.bundle to Directory instead of Bundle in order to see a disclosure triangle next to it so that you can expand it and select Root .plist.)

4. Click Run. Tap the Home button to end the application, and tap the Settings application’s icon. The Settings application includes MySettings (Figure 14-3). Tap the arrow, and Settings displays the MySettings application’s default settings screen (Figure 14-4).

NOTE
To change this example’s title displayed in Settings, change the application’s Bundle Display Name in the MySettings-Info.plist file (Figure 14-5).

Image

Figure 14-3 Settings application with MySettings

Image

Figure 14-4 MySettings application’s settings

Image

Image

Figure 14-5 Changing the application’s name

Settings Field Types

You add preferences to the settings bundle through Root.plist. The different settings display differently in the Settings application. Possible values for settings are PSTextFieldSpecifier, PSTitleValueSpecifier, PSToggleSwitchSpecifier, PSMultiValueSpecifier, PSGroupSpecifier, and PSChildPaneSpecifier. This section considers each setting in turn.

TIP
We use the word “expand” rather than “disclose” throughout this book. In this chapter, you will notice you “expand” rows; you don’t “disclose” them. The little arrows, called Disclosure buttons, when clicked, are said to “disclose” their content.

PSGroupSpecifier

The PSGroupSpecifier groups settings into a group. If you have many settings, consider using this specifier to group your settings into logical groupings. Table 14-1 summarizes the PSGroupSpecifier’s settings.

PSTextFieldSpecifier

The PSTextFieldSpecifier is for a preference whose value is a string. Table 14-2 summarizes a PSTextFieldSpecifier’s settings.

Image

Table 14-1 PSGroupSpecifier Settings

Image

Table 14-2 PSTextFieldSpecifier Settings

Try This
Adding a PSTextFieldSpecifier

1. Open MySettings in Xcode. Open Root.plist in the Editor window.

2. Expand PreferenceSpecifiers and delete Item 1, Item 2, and Item 3, leaving just Item 0.

3. Select Item 0 and click the plus sign to its right. It adds a new row (Item 1). Note that this row is a child of PreferenceSpecifiers.

4. Select Item 1 and change its type to Dictionary.

5. Control-click Item 1, expand it, and select Add Row. A new child row should be added. Note that this row is a child of Item 1. Add two more new child rows; ensure that they are children of Item 1. Change each row to match Figure 14-6.

6. Save the .plist file.

7. Click Run. Navigate to Settings and MySettings settings. Click the text field, and your Simulator should match Figure 14-7.

Image

Figure 14-6 Root.plist with PSTextFieldSpecifier

Image

Figure 14-7 Settings reflecting the new setting

Image

Table 14-3 PSMultiValueSpecifier Settings

PSMultiValueSpecifier

The PSMultiValueSpecifier is for selecting one of many alternative choices. Table 14-3 summarizes the PSMultiValueSpecifier’s settings. Note that you create entries below the Values and Titles settings for each value and for each title.

Try This
Adding a PSMultiValueSpecifier

1. Return to MySettings in Xcode. Open the Root.plist in the editor.

2. Create an Item 2 below PreferenceSpecifiers and ensure its type is Dictionary.

3. Expand Item 2 and add six new child rows.

4. Change the first child row to have Type for the key, String for the type, and PSMultiValueSpecifier for the value (Figure 14-8).

5. Change the next child row to have Title for the key, String for the type, and Colors for the value.

6. Change the next child row to have DefaultValue for the key, String for the type, and blue for the value.

7. Change the next child row to have Key for the key, String for the type, and keyTwo for the value.

8. Change the next two child rows to have Titles and then Values for the key and Array for the type.

9. Expand Titles and then add three child rows to it. Do the same for Values (see Figure 14-8). Assign the three child Titles the values Red, Blue, and Orange. Assign the three child Values the values red, blue, and orange.

10. Save the .plist file.

11. Click Run. Navigate to the Settings application, and the new setting appears (Figure 14-9).

Image

Figure 14-8 Root.plist with the PSMultiValueSpecifier added

Image

Figure 14-9 Settings reflecting the new setting

Image

Table 14-4 PSToggleSwitchSpecifier Settings

PSToggleSwitchSpecifier

The PSToggleSwitchSpecifier is for selecting a Boolean value. The toggle switch displayed in the Settings application for this specifier is On or Off. Table 14-4 summarizes the PSToggleSwitchSpecifier’s settings.

Try This
Adding a PSToggleSwitchSpecifier

1. Return to Root.plist and add Item 3 below PreferenceSpecifiers (i.e., highlight Item 2 and click the plus sign on the right). Change the new item’s type to Dictionary.

2. Expand Item 3 and add six new child rows. Change the first child row to have a Type for key, String for type, and PSToggleSwitchSpecifier for value. Change the second child row to have Title for key, String for type, and Use Colors? for the value. Change the third child row to have Key for key, String for type, and keyThree for value. Change the fourth child row to have TrueValue for key, String for type, and YES for value. Change the fifth child row to have FalseValue for key, String for type, and NO for value. Finally, change the sixth child row to have DefaultValue for key, String for type, and NO for value (Figure 14-10).

3. Save the .plist file.

4. Click Run. Navigate to Settings, and the new value appears (Figure 14-11).

NOTE
Notice we keep stating to “save the .plist file” as its own step. The reason for this is that Run does not automatically save the .plist file.

Image

Figure 14-10 Root.plist with the PSToggleSwitchSpecifier added

Image

Figure 14-11 Settings reflecting the new setting

Image

Table 14-5 PSSliderSpecifier Settings

PSSliderSpecifier

The PSSliderSpecifier is for selecting a value from a range of values. Table 14-5 summarizes PSSliderSpecifier’s settings.

Try This
Adding a PSSliderSpecifier

1. Return to Root.plist and add a new item below Item 3.

2. Change the newly added item to a Dictionary type. Expand the new Item 4 and add two child rows below it.

3. Assign the first child item’s key to Type, type to String, and value to PSGroupSpecifier.

4. Assign the second child item’s key to Title, type to String, and value to Intensity.

5. Close Item 4 and add another item after it. Change the new Item 5’s type to Dictionary. Expand the newly added item and add six child rows.

6. Change the first child row’s key to Type, type to String, and value to PSSliderSpecifier. Change the third child row’s key to Key, type to String, and value to keyFour. Change the fourth child row’s key to DefaultValue, type to Number, and value to 5. Change the fifth child row’s key to MinimumValue, type to Number, and value to 0. Change the sixth child row’s key to MaximumValue, type to Number, and value to 10. Figure 14-12 shows Root. plist after making the changes.

7. Save the .plist file.

8. Click Run, and the changes appear in the Settings application (Figure 14-13).

Image

Figure 14-12 Root.plist with the PSSliderSpecifier added

Image

Figure 14-13 Settings reflects the new setting

Image

Table 14-6 PSChildPaneSpecifier Settings

PSChildPaneSpecifier

The PSChildPaneSpecifier is for specifying a child pane in the Settings application. You define the settings in this pane in a separate .plist file. Table 14-6 summarizes PSChildSpecifier’s settings.

Try This
Adding a PSChildPaneSpecifier

1. Return to Root.plist and add Item 6. Change its type to Dictionary. Expand and add three child rows.

2. Change the first child row’s key to Type, type to String, and value to PSChildPaneSpecifier. Change the second child row’s key to Title, type to String, and value to Shade. Change the third child row’s key to File, type to String, and value to Shades (Figure 14-14).

Image

Figure 14-14 Root.plist with the PSChildPaneSpecifier added

Image

Figure 14-15 Creating a new property list

3. Save.

4. Create a new property list (Figure 14-15). Name the file Shades.

5. Open Shades.plist in the editor and add one row. Change the row’s key to Title, type to String, and value to Shades (Figure 14-16).

6. Save.

7. Click Build And Go. The change is reflected in the Settings application (Figure 14-17).

Image

Figure 14-16 The Shades.plist settings

Image

Figure 14-17 Application’s settings pane shows the new subpane

Reading Settings Using NSUserDefaults

You use the NSUserDefaults class to access the defaults system. The defaults for an application are loaded at startup time and cached. You access these values using the NSUserDefaults class’s methods. Methods for obtaining values include arrayForKey:, boolForKey:, dataForKey:, dictionaryForKey:, floatForKey:, integerForKey:, objectForKey:, stringArrayForKey:, and stringForKey:. For instance, to obtain a string value from a key holding a string, you use the stringForKey: method.

NSString* value = [[[NSUserDefaults standardUserDefaults]
stringForKey:@"myKey"] retain];

Try This
Reading the Settings Bundle

1. Open MySettingsAppDelegate.m and modify applicationDidFinishLaunchingWithOptions: to log the application’s settings (Listing 14-1). Notice that you also initialize the application’s settings.

Listing 14-1 The applicationDidFinishLaunchingWithOptions method in MySettingsAppDelegate

(BOOL)application:(UIApplication *)application
          didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
  NSString *testValue = [[NSUserDefaults standardUserDefaults]
                               stringForKey:@"keyOne"];
  if (testValue == nil) {
    NSDictionary *appDefaults =
                 [NSDictionary dictionaryWithObjectsAndKeys:
                         @"keyOneValue", @"keyOne",@"keyTwoValue",
                         @"keyTwo",@"0", @"keyThree", @"keyFourValue",
                         @"keyFour", nil];
    [[NSUserDefaults standardUserDefaults]
           registerDefaults: appDefaults];
    [[NSUserDefaults standardUserDefaults] synchronize];
  }
  NSUserDefaults * defaults = [NSUserDefaults standardUserDefaults];
  NSLog(@"%@",[defaults stringForKey:@"keyOne"]);
  NSLog(@"%@",[defaults stringForKey:@"keyTwo"]);
  NSLog(@"%@",[defaults stringForKey:@"keyThree"]);
  NSLog(@"%@",[defaults stringForKey:@"keyFour"]);
  [window addSubview:viewController.view];
  [window makeKeyAndVisible];
  return YES;
}

2. Click Run. The Debugger Console logs the default values (Listing 14-2).

Listing 14-2 Debugger Console logging settings

2010-09-11 00:53:00.407 MySettings[12014:207] keyOneValue
2010-09-11 00:53:00.409 MySettings[12014:207] keyTwoValue
2010-09-11 00:53:00.410 MySettings[12014:207] 0
2010-09-11 00:53:00.410 MySettings[12014:207] keyFourValue

3. Tap the Home button and navigate to the Settings application. Change MySetting’s values. Exit the Settings application. Terminate the iPhone Simulator.

4. Click Run again, and this time, the values you changed in the Settings application should appear in the Debugger Console.

Notice the console does not log the text value represented by keyOne. This is because you did not specify a default value. If you navigate to the Settings application, add a value for the text field, and then exit Settings, the next time you start the application, keyOne will log a value.

Although not well documented, in Apple’s AppSettings sample application, code is provided that handles uninitialized preferences. Listing 14-1 uses the sample application’s logic to first check if the first setting was set. If not, it creates default settings for the user settings values. Note that it doesn’t save these values, though. Until a user actually goes into the Settings application and changes the settings, the MySettings application’s user preferences will always default to the values set in the applicationDidFinishLaunching: method.

Changed Settings While Suspended

Prior to iOS 4, when the user pressed the Home button to leave your application, your application was terminated and unloaded from memory. If that user went to the Settings and changed your application’s settings, you would notice the change when loading settings NSUserDefaults in applicationDidFinishLaunchingWithOptions the next time your application launched. However, any new applications that are built for iOS 4 now default to supporting a limited version of multitasking. When the user presses the Home button, your application is initially only suspended. If they launch your application again, iOS just resumes it where it left off. If the user changed your settings while it was suspended, you will need to notice the change.

Fortunately, there is an easy way to watch for new settings. When your settings are changed, iOS will send your application a NSUserDefaultsDidChangeNotification. Register for this notification when your application initially launches and you’ll be able to react to any settings changes that might occur while your application is running.

[[NSNotificationCenter defaultCenter] addObserver:self
    selector:selector(settingsHaveChanged)
    name: NSUserDefaultsDidChangeNotification object:nil]

When your settingsHaveChanged method is called, call [notification object] to get the NSUserDefaults object.

Summary

It is important to remember that application settings are for preferences that will not change often. For instance, a user’s username, password, and e-mail address are not likely to change often. An application’s preferences are set up using the Root.plist and zero or more plists for child panes. Users modify an application’s preferences through the Settings application. The application can access its preferences through the NSUserDefault class.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset