iPhone应用程序:如何从root.plist获取默认值?

时间:2009-09-16 05:46:21

标签: iphone objective-c xcode

我正在开发iPhone应用程序

我从root.plist中读取了一个关键字:

NSString *Key1Var = [[NSUserDefaults standardUserDefaults] stringForKey:@"Key1"];

(“Key1”是PSMultiValueSpecifier,已在root.plist中设置了默认字符串值)

一旦用户进行设置,该工作正常。 但是如果用户在进行任何设置之前运行应用程序,他将获得“{1}}”的“Key1”。 在这种情况下,我期待我为“Key1”设置的默认值。 我需要做什么, 这样用户不必进行设置,第一次运行应用程序?

此致 哈里什

7 个答案:

答案 0 :(得分:14)

有关完整的解决方案,请参阅this question

您基本上希望在访问设置之前运行此代码:

- (void)registerDefaultsFromSettingsBundle {
    NSString *settingsBundle = [[NSBundle mainBundle] pathForResource:@"Settings" ofType:@"bundle"];
    if(!settingsBundle) {
        NSLog(@"Could not find Settings.bundle");
        return;
    }

    NSDictionary *settings = [NSDictionary dictionaryWithContentsOfFile:[settingsBundle stringByAppendingPathComponent:@"Root.plist"]];
    NSArray *preferences = [settings objectForKey:@"PreferenceSpecifiers"];

    NSMutableDictionary *defaultsToRegister = [[NSMutableDictionary alloc] initWithCapacity:[preferences count]];
    for(NSDictionary *prefSpecification in preferences) {
        NSString *key = [prefSpecification objectForKey:@"Key"];
        if(key) {
            [defaultsToRegister setObject:[prefSpecification objectForKey:@"DefaultValue"] forKey:key];
        }
    }

    [[NSUserDefaults standardUserDefaults] registerDefaults:defaultsToRegister];
    [defaultsToRegister release];
}

这会将默认值加载到standardUserDefaults对象中,这样您就不会再获取nil值,也不必复制代码中的默认设置。

答案 1 :(得分:4)

在我尝试获取设置之前,我会在发布后尽早完成此操作:

    userDefaultsValuesPath=[[NSBundle mainBundle] pathForResource:@"UserDefaults"
                                                           ofType:@"plist"];
    userDefaultsValuesDict=[NSDictionary dictionaryWithContentsOfFile:userDefaultsValuesPath];

    // set them in the standard user defaults
    [[NSUserDefaults standardUserDefaults] registerDefaults:userDefaultsValuesDict];

    if (![[NSUserDefaults standardUserDefaults] synchronize])
        NSLog(@"not successful in writing the default prefs");

答案 2 :(得分:3)

以下是我在iOS 7中使用的代码,主要基于Mike Weller上面的代码。

将此方法放在AppDelegate.m中:

- (void)registerDefaultsFromSettingsBundleWithPlist:(NSString *)plist {
NSString *settingsBundle = [[NSBundle mainBundle] pathForResource:@"Settings" ofType:@"bundle"];
if(!settingsBundle) {
    NSLog(@"Could not find Settings.bundle");
    return;
}
NSString *bundle = [NSString stringWithFormat:@"%@.plist",plist];
NSDictionary *settings = [NSDictionary dictionaryWithContentsOfFile:[settingsBundle stringByAppendingPathComponent:bundle]];
NSArray *preferences = [settings objectForKey:@"PreferenceSpecifiers"];

NSMutableDictionary *defaultsToRegister = [[NSMutableDictionary alloc] initWithCapacity:[preferences count]];
for(NSDictionary *prefSpecification in preferences) {
    NSString *key = [prefSpecification objectForKey:@"Key"];
    if(key) {
        [defaultsToRegister setObject:[prefSpecification objectForKey:@"DefaultValue"] forKey:key];
    }
}

[[NSUserDefaults standardUserDefaults] registerDefaults:defaultsToRegister];
//[defaultsToRegister release];
}

然后在代码的早期某个地方(如didFinishLaunchingWithOptions)为您正在使用的每个设置文件(针对嵌套设置)调用它:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
//register default settings into NSUserDefaults
    @try {
        [self registerDefaultsFromSettingsBundleWithPlist:@"Root"];
        [self registerDefaultsFromSettingsBundleWithPlist:@"Chat"];
        [self registerDefaultsFromSettingsBundleWithPlist:@"IVR"];
        [self registerDefaultsFromSettingsBundleWithPlist:@"Video"];
    }
    @catch (NSException * e) {
        NSLog(@"Exception: %@", e);
        NSLog(@"Try adding the Default Value field to each preference item in the Settings.bundle plist files.");
    }
    @finally {

    }
    ...

答案 3 :(得分:2)

我已将Mike Weller的解决方案翻译成Swift 2.0 / iOS 9并使其适用于我的应用程序:

func registerDefaultsFromSettingsBundle() {
    guard let settingsBundle = NSBundle.mainBundle().URLForResource("Settings", withExtension:"bundle") else {
        NSLog("Could not find Settings.bundle")
        return;
    }

    guard let settings = NSDictionary(contentsOfURL: settingsBundle.URLByAppendingPathComponent("Root.plist")) else {
        NSLog("Could not find Root.plist in settings bundle")
        return
    }

    guard let preferences = settings.objectForKey("PreferenceSpecifiers") as? [[String: AnyObject]] else {
        NSLog("Root.plist has invalid format")
        return
    }

    var defaultsToRegister = [String: AnyObject]()
    for var p in preferences {
        if let k = p["Key"] as? String, v = p["DefaultValue"] {
            NSLog("%@", "registering \(v) for key \(k)")
            defaultsToRegister[k] = v
        }
    }

    NSUserDefaults.standardUserDefaults().registerDefaults(defaultsToRegister)
}

答案 4 :(得分:2)

基于Mike Weller's原始解决方案的Swift 3版本,如果有人需要它:

static func registerDefaultsFromSettingsBundle() {

    guard let settingsBundle = Bundle.main.url(forResource: "Settings", withExtension: "bundle") else {
        print("Could not find Settings.bundle")
        return
    }
    guard let settings = NSDictionary(contentsOf: settingsBundle.appendingPathComponent("Root.plist")) else {
        print("Couldn't find Root.plist in settings bundle")
        return
    }

    guard let preferences = settings.object(forKey: "PreferenceSpecifiers") as? [[String: AnyObject]] else {
        print("Root.plist has an invalid format")
        return
    }

    var defaultsToRegister = [String: AnyObject]()
    for var p in preferences {
        if let k = p["Key"] as? String, let v = p["DefaultValue"] {
            print("Registering " + v.debugDescription + " for key " + k)
            defaultsToRegister[k] = v as AnyObject
        }
    }

    UserDefaults.standard.register(defaults: defaultsToRegister)
}

答案 5 :(得分:0)

在我的应用程序委托中,我覆盖+initialize方法并注册新的应用程序默认首选项。

例如:

+ (void) initialize {
    if ([self class] == [MyAppDelegate class]) {        
        // initialize user defaults dictionary
        BOOL isFirstTimeRun = YES;
        BOOL isKeychainTurnedOn = NO;
        BOOL isSSLTurnedOn = YES;
        NSString *testURLString = @"http://stackoverflow.com";
        NSMutableDictionary *resourceDict = [NSMutableDictionary dictionary];
        [resourceDict setObject:[NSNumber numberWithBool:isFirstTimeRun] forKey:kIsFirstTimeRunKey];
        [resourceDict setObject:[NSNumber numberWithBool:isKeychainTurnedOn] forKey:kIsKeychainTurnedOnKey];
        [resourceDict setObject:[NSNumber numberWithBool:isSSLTurnedOn] forKey:kIsSSLTurnedOnKey];
        [resourceDict setObject:testURLString forKey:kTestURLString];
        [[NSUserDefaults standardUserDefaults] registerDefaults:resourceDict];
    }
}

答案 6 :(得分:0)

NSBundle* mainBundle = [NSBundle mainBundle]; 

// Reads the value of the custom key I added to the Info.plist
NSString *value = [mainBundle objectForInfoDictionaryKey:@"key"];

//Log the value
NSLog(@"Value = %@", value);

// Get the value for the "Bundle version" from the Info.plist
[mainBundle objectForInfoDictionaryKey:@"CFBundleVersion"];

// Get the bundle identifier
[mainBundle bundleIdentifier];