NSUserDefaults在模拟器上首次运行时不存在

时间:2010-05-08 04:31:01

标签: iphone nsuserdefaults

我在Settings.bundle中保存了一些设置,我尝试在application:didFinishLaunchingWithOptions中使用它们,但是在模拟器上第一次按键访问对象时总是返回nil(或在整数的情况下为0)。一旦我进入设置屏幕然后退出,它们就可以在之后的每次运行中正常工作。

发生了什么事?在Settings.bundle中使用默认值是否能够在不要求用户首先输入的情况下使用它们?

4 个答案:

答案 0 :(得分:5)

如果我的问题是正确的,请在你的app委托 - (void)applicationDidFinishLaunching:(UIApplication *)应用程序中,通过调用设置设置的默认值 registerDefaults:dictionaryWithYourDefaultValues 在[NSUserDefaults standardUserDefaults]

- (void)applicationDidFinishLaunching:(UIApplication *)application {    
    NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
    NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:
                          [NSNumber numberWithInt:3], @"SomeSettingKey",
                          @"Some string value", @"SomeOtherSettingKey",
                          nil];
    [ud registerDefaults:dict];
}

只有在以前的应用程序执行中未设置或更改这些设置时,才会使用这些值。

答案 1 :(得分:3)

正如coneybeare所说:“你应该检测它是否是第一次加载,然后最初存储你所有的默认值。”

在applicationDidFinishLaunching上尝试在您的首选项中设置默认值。

以下是样本:

NSUserDefaults *defaults =[NSUserDefaults standardUserDefaults];
if([defaults objectForKey:@"YOUR_KEY"] == nil)
{
    [defaults setValue:@"KEY_VALUE" forKey:@"YOUR_KEY"];
}

当应用程序第二次运行时,它将为KEY_VALUE提供YOUR_KEY。

谢谢,
吉姆。

答案 2 :(得分:2)

  

不是默认使用的重点   Settings.bundle中的值为   能够使用它们而不需要   用户先输入?

没有。设置包的要点是为用户提供在方便的位置编辑所有第三方应用程序设置的位置。这种集中化是否真的是一个好主意是一个偏离主题的用户体验问题。

要回答您的问题,您应该检测它是否是第一次加载,然后存储所有默认值。

在我们讨论这个主题时,我还会查看In App Settings Kit,因为它为您的应用提供了一种简单的方法,可以在最少的代码中在两个地方(应用内和设置.app)中显示您的应用设置

答案 3 :(得分:2)

Settings.bundle中的值适用于“设置”应用,可以为您的应用填写默认值。它们不会被您自己的应用使用。 但您可以使用NSUserDefaults的registerDefaults:方法自行设置默认值。这实际上不会将它们设置在磁盘上,而只是给出“默认值”:当用户尚未设置任何值时使用它们。

设置registerDefaults:必须在使用默认值之前完成。其他人为此提出的“applicationDidFinishLaunching:”方法在大多数情况下为时已晚。到“applicationDidFinishLaunching:”被调用时,您的视图已经从nib文件加载,并且已经调用了它们的“viewDidLoad:”方法。他们通常可以读取用户默认值。

为了保证在第一次使用之前设置默认值,我使用以下实用程序类,它从Root.plist文件加载值并使用“registerDefaults:”设置它们。您使用此类来读取用户默认值而不是“[NSUserDefaults standardUserDefaults]”。请改为使用“[设置获取]”。

作为奖励,它还包含用户默认更改通知的注册方法,因为我总是忘记这是如何完成的。

#import "Settings.h"


@implementation Settings

static bool initialized = NO;

+ (void) setDefaults
{
    NSString *bundlePath = [[NSBundle mainBundle] bundlePath];
    NSString *settingsBundlePath = [bundlePath    stringByAppendingPathComponent:@"Settings.bundle"];
    NSBundle *settingsBundle = [NSBundle bundleWithPath:settingsBundlePath];
    NSString *settingsPath = [settingsBundle pathForResource:@"Root" ofType:@"plist"];

    NSDictionary *settingsDict = [NSDictionary     dictionaryWithContentsOfFile:settingsPath];
    NSArray *prefSpecifierArray = [settingsDict objectForKey:@"PreferenceSpecifiers"];

    NSMutableDictionary *appDefaults = [[NSMutableDictionary alloc] init];
    for (NSDictionary *prefItem in prefSpecifierArray)
    {
        NSString *key = [prefItem objectForKey:@"Key"];
        if (key != nil) {
            id defaultValue = [prefItem objectForKey:@"DefaultValue"];
            [appDefaults setObject:defaultValue forKey:key];
        }
    }

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

    if (![[NSUserDefaults standardUserDefaults] synchronize]) {
        NSLog(@"Settings setDefaults: Unsuccessful in writing the default settings");
    }
}

+ (NSUserDefaults *)get
{
    if (!initialized) {
        [Settings setDefaults];
        initialized = YES;
    }
    return [NSUserDefaults standardUserDefaults];
}

+ (void) registerForChange:(id)observer selector:(SEL)method
{
    [[NSNotificationCenter defaultCenter] addObserver:observer selector:method name:NSUserDefaultsDidChangeNotification object:nil];
}

+ (void) unregisterForChange:(id)observer
{
    [[NSNotificationCenter defaultCenter] removeObserver:observer name:NSUserDefaultsDidChangeNotification object:nil];
}