/* |
Copyright (C) 2014 Apple Inc. All Rights Reserved. |
See LICENSE.txt for this sample’s licensing information |
|
Abstract: |
|
The application' delegate. Handles loading and registering the default values |
for each setting from the Settings bundle. |
*/ |
|
#import "AppPrefsAppDelegate.h" |
|
@implementation AppPrefsAppDelegate |
|
//| ---------------------------------------------------------------------------- |
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions |
{ |
// The registration domain is volatile. It does not persist across launches. |
// You must register your defaults at each launch; otherwise you will get |
// (system) default values when accessing the values of preferences the |
// user (via the Settings app) or your app (via set*:forKey:) has not |
// modified. Registering a set of default values ensures that your app |
// always has a known good set of values to operate on. |
[self populateRegistrationDomain]; |
|
return YES; |
} |
|
|
//| ---------------------------------------------------------------------------- |
//! Locates the file representing the root page of the settings for this app, |
//! invokes loadDefaults:fromSettingsPage:inSettingsBundleAtURL: on it, |
//! and registers the loaded values as the app's defaults. |
// |
- (void)populateRegistrationDomain |
{ |
NSURL *settingsBundleURL = [[NSBundle mainBundle] URLForResource:@"Settings" withExtension:@"bundle"]; |
|
// Invoke loadDefaultsFromSettingsPage:inSettingsBundleAtURL: on the property |
// list file for the root settings page (always named Root.plist). |
NSDictionary *appDefaults = [self loadDefaultsFromSettingsPage:@"Root.plist" inSettingsBundleAtURL:settingsBundleURL]; |
|
// appDefaults is now populated with the preferences and their default values. |
// Add these to the registration domain. |
[[NSUserDefaults standardUserDefaults] registerDefaults:appDefaults]; |
[[NSUserDefaults standardUserDefaults] synchronize]; |
} |
|
|
//| ---------------------------------------------------------------------------- |
//! Helper function that parses a Settings page file, extracts each preference |
//! defined within along with its default value. If the page contains a |
//! 'Child Pane Element', this method will recurs on the referenced page file. |
// |
- (NSDictionary*)loadDefaultsFromSettingsPage:(NSString*)plistName inSettingsBundleAtURL:(NSURL*)settingsBundleURL |
{ |
// Each page of settings is represented by a property-list file that follows |
// the Settings Application Schema: |
// </RU/iOS/#documentation/PreferenceSettings/Conceptual/SettingsApplicationSchemaReference/Introduction/Introduction.html>. |
|
// Create an NSDictionary from the plist file. |
NSDictionary *settingsDict = [NSDictionary dictionaryWithContentsOfURL:[settingsBundleURL URLByAppendingPathComponent:plistName]]; |
|
// The elements defined in a settings page are contained within an array |
// that is associated with the root-level PreferenceSpecifiers key. |
NSArray *prefSpecifierArray = settingsDict[@"PreferenceSpecifiers"]; |
|
// If prefSpecifierArray is nil, something wen't wrong. Either the |
// specified plist does ot exist or is malformed. |
if (prefSpecifierArray == nil) |
return nil; |
|
// Create a dictionary to hold the parsed results. |
NSMutableDictionary *keyValuePairs = [NSMutableDictionary dictionary]; |
|
for (NSDictionary *prefItem in prefSpecifierArray) |
// Each element is itself a dictionary. |
{ |
// What kind of control is used to represent the preference element in the |
// Settings app. |
NSString *prefItemType = prefItem[@"Type"]; |
// How this preference element maps to the defaults database for the app. |
NSString *prefItemKey = prefItem[@"Key"]; |
// The default value for the preference key. |
NSString *prefItemDefaultValue = prefItem[@"DefaultValue"]; |
|
if ([prefItemType isEqualToString:@"PSChildPaneSpecifier"]) |
// If this is a 'Child Pane Element'. That is, a reference to another |
// page. |
{ |
// There must be a value associated with the 'File' key in this preference |
// element's dictionary. Its value is the name of the plist file in the |
// Settings bundle for the referenced page. |
NSString *prefItemFile = prefItem[@"File"]; |
|
// Recurs on the referenced page. |
NSDictionary *childPageKeyValuePairs = [self loadDefaultsFromSettingsPage:prefItemFile inSettingsBundleAtURL:settingsBundleURL]; |
|
// Add the results to our dictionary |
[keyValuePairs addEntriesFromDictionary:childPageKeyValuePairs]; |
} |
else if (prefItemKey != nil && prefItemDefaultValue != nil) |
// Some elements, such as 'Group' or 'Text Field' elements do not contain |
// a key and default value. Skip those. |
{ |
keyValuePairs[prefItemKey] = prefItemDefaultValue; |
} |
} |
|
return keyValuePairs; |
} |
|
@end |