iphone dev - проверка NSUserDefaults на наличие логического значения

Я только что добавил пакет настроек в свое приложение, и у меня возникли проблемы с чтением настроек bool. Я знаю, что при запуске приложения настройки не считываются, пока пользователь их не введет, и это то, что я пытаюсь зафиксировать.

Однако мой код просто фиксирует, если ответ НЕТ ИЛИ они не были установлены. Мне нужно узнать, были ли они установлены, ТОГДА установить ответы!

код настройки:

BOOL playSound;
BOOL playVibrate;


//test for some defaults
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
if (![prefs boolForKey:@"pref_sound"]) {
    playSound = YES;
    playVibrate = YES; 
} else {
    playSound = [prefs boolForKey:@"pref_sound"];
    playVibrate = [prefs boolForKey:@"pref_vibrate"]; 
}


if (playSound) {
//do stuff
}

проблема в том, что если пользователь устанавливает для настроек значение «НЕТ», код затем меняет как вибрацию, так и звук на «да», что предназначено для захвата НЕ установки....

Любые идеи?


person Matt Facer    schedule 27.12.2009    source источник


Ответы (3)


Во-первых, у вас есть ошибка в условном выражении if. Вы проверяете само логическое значение, которое, согласно boolForKey: документация, вернет NO, если она еще не установлена. Так что boolForKey: - неправильный способ сделать это.

Вот еще две идеи.

Рассмотрите возможность использования другого параметра с другим ключом, чтобы указать, были ли ваши параметры инициализированы. Проверяйте его при запуске приложения или при первом чтении настроек. Инициализировать при необходимости. Например:

- (void) initializeUserDefaults {
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    if (nil == [defaults objectForKey:@"initialized_defaults"]) {
        [defaults setBool:YES forKey:@"pref_sound"];
        [defaults setBool:YES forKey:@"pref_vibrate"];
        [defaults setObject:@"dummy_value" forKey:@"initialized_defaults"];
    }
}

Более простым решением (но я не уверен, что это сработает) было бы изменить ваше условное выражение на чтение:

if (![prefs objectForKey:@"pref_sound"]) {

Опять же, я не знаю, будет ли это делать то, что я себе представляю, но я предполагаю, что objectForKey: вернет базовый упакованный логический объект, если он там есть, или nil.

Если вы добавляете новый параметр в новую версию своего приложения, вы не хотите, чтобы ваши новые параметры были неинициализированы, и вы не хотите топтаться по существующим параметрам ваших пользователей. Второй метод делает это без усилий, а в первом легче напортачить. Но первый метод также собирает все ваши настройки в одном месте, чтобы вы могли увидеть, как это должно работать, что мне нравится.

Я не уверен, что документы ADC сочли бы передовой практикой. Чтобы выяснить это, я предлагаю вам просмотреть любые примеры кода, на которые есть ссылки в справочнике по классам NSUserDefaults.

person Kevin Conner    schedule 27.12.2009
comment
спасибо за это - кажется, что objectForKey сделал свое дело! Я заметил, что boolForKey вернет NO, если не установлен, поэтому попробовал == nil, но это не сработало. Благодарность :) - person Matt Facer; 27.12.2009
comment
С удовольствием :) Последний совет: используйте двойной щелчок в Xcode. Документация Apple удивительно тщательна, поэтому вы обычно можете решить свои проблемы с помощью того, что делает этот метод? Ваше здоровье! - person Kevin Conner; 27.12.2009
comment
Убедитесь, что вы используете [defaults synchronize]; в конце этого оператора if для синхронизации значений. - person mattblessed; 11.01.2014


Решение Кевина Коннера работает для меня, но есть еще одна вещь, которую, я думаю, я должен указать.

Мое приложение отдает предпочтение правшам по умолчанию. Когда я нажимаю «Выполнить» в Xcode, использую приложение, чтобы изменить мои предпочтения на левшу, а затем запускаю его во второй раз, мои предпочтения по-прежнему остаются правшами.

Кажется, что запуск в Xcode стирает настройки. Я решил вручную выйти из приложения изнутри симулятора, снова открыть его изнутри, а затем увидел свои новые настройки.

person David Braun    schedule 12.07.2012
comment
Дэвид, поведение, которое вы видите, может быть связано с тем, как вы завершаете свой первый запуск отладки. Если вы нажмете кнопку остановки в XCode, nsuserdefaults может не синхронизироваться до того, как процесс будет уничтожен. Если вы выходите из приложения из симулятора, синхронизация происходит. - person software evolved; 14.03.2013