NSUserDefaults - как узнать, существует ли ключ


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

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

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

Пример 2: он говорит: "Привет [имя]", где имя-это то, что вы вступили. Если вы открыли приложение и нет имени, он должен сказать "Привет Мир.- Мне нужно проверить, ввели ли вы уже имя, и действовать соответственно. Имя будет сохранено в NSUserDefaults.

какая-то помощь здесь? Я бы очень ценю это!

11 194

11 ответов:

objectForKey: вернутся nil если он не существует.

Как упоминалось выше, он не будет работать для примитивных типов, где 0 / NO может быть допустимым значением. Я использую этот код.

NSUserDefaults *defaults= [NSUserDefaults standardUserDefaults];
if([[[defaults dictionaryRepresentation] allKeys] containsObject:@"mykey"]){

    NSLog(@"mykey found");
}

The objectForKey: метод возвращает nil если значение не существует. Вот простой тест IF / THEN, который скажет вам, если значение равно nil:

if([[NSUserDefaults standardUserDefaults] objectForKey:@"YOUR_KEY"] != nil) {
    ...
}

"objectForKey вернет nil, если он не существует. " Он также вернет nil, если он существует, и это либо целое число, либо логическое значение со значением нуля (т. е. FALSE или NO для булева).

Я проверил это в тренажер для 5.1 и 6.1. Это означает, что вы не можете проверить, были ли заданы целые числа или логические значения, запросив "объект". Вы можете уйти с этим для целых чисел, если вы не возражаете относиться к "не установлен", как если бы это было "в ноль".

люди, которые уже проверяли это, похоже, были обмануты ложным отрицательным аспектом, т. е. проверяя это, видя, возвращает ли objectForKey nil, когда вы знаете, что ключ не был установлен, но не замечая, что он также возвращает nil, если ключ был установлен, но был установлен в NO.

для моей собственной проблемы, которая отправила меня сюда, я просто изменил семантику моего логического значения, чтобы мое желаемое значение по умолчанию соответствовало значению NO. Если это не вариант, вам нужно будет хранить как что-то другое, чем логическое, и убедитесь, что вы можете определить разницу между YES, NO и "not set."

попробуйте эту маленькую пышку:

-(void)saveUserSettings{
NSNumber*   value;

value = [NSNumber numberWithFloat:self.sensativity];
[[NSUserDefaults standardUserDefaults] setObject:value forKey:@"sensativity"];
}
-(void)loadUserSettings{
    NSNumber*   value;
    value = [[NSUserDefaults standardUserDefaults] objectForKey:@"sensativity"];
    if(value == nil){
        self.sensativity = 4.0;
    }else{
        self.sensativity = [value floatValue];
    }
}

рассматривать все как объект. Кажется, работает на меня.

Swift версия, чтобы получить Bool?

NSUserDefaults.standardUserDefaults().objectForKey(DefaultsIsGiver) as? Bool

расширения UserDefaults один раз, чтобы не копировать-вставить это решение:

extension UserDefaults {

    func hasValue(forKey key: String) -> Bool {
        return nil != object(forKey: key)
    }
}

// Example
UserDefaults.standard.hasValue(forKey: "username")

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

вот что я сделал. У меня был BOOL, который носился в переменной под названием "_talkative".

когда я устанавливаю свой объект по умолчанию (NSUserDefaults), я устанавливаю его как объект как я мог бы проверить, чтобы увидеть, если это было шь:

//converting BOOL to an object so we can check on nil
[defaults setObject:@(_talkative) forKey:@"talkative"];

затем, когда я пошел посмотреть, существует ли он, я использовал:

if ([defaults objectForKey:@"talkative"]!=nil )
  {

затем я использовал объект в качестве BOOL:

if ([defaults boolForKey:@"talkative"]) {
 ...

Это, кажется, работает в моем случае. Это просто имело больше визуального смысла для меня.

Swift 3 / 4:

вот простое расширение для типов int/Double/Float / Bool key-value, которые имитируют поведение необязательного возврата других типов, доступных через UserDefaults.

(Редактировать 30 Августа 2018: обновлено с более эффективным синтаксисом из предложения Лео.)

extension UserDefaults {
    /// Convenience method to wrap the built-in .integer(forKey:) method in an optional returning nil if the key doesn't exist.
    func integerOptional(forKey: String) -> Int? {
        return self.object(forKey: forKey) as? Int
    }
    /// Convenience method to wrap the built-in .double(forKey:) method in an optional returning nil if the key doesn't exist.
    func doubleOptional(forKey: String) -> Double? {
        return self.object(forKey: forKey) as? Double
    }
    /// Convenience method to wrap the built-in .float(forKey:) method in an optional returning nil if the key doesn't exist.
    func floatOptional(forKey: String) -> Float? {
        return self.object(forKey: forKey) as? Float
    }
    /// Convenience method to wrap the built-in .bool(forKey:) method in an optional returning nil if the key doesn't exist.
    func boolOptional(forKey: String) -> Bool? {
        return self.object(forKey: forKey) as? Bool
    }
}

теперь они более последовательны наряду с другими встроенными методами get (string, data и т. д.). Просто используйте методы get вместо старых те.

let AppDefaults = UserDefaults.standard

// assuming the key "Test" does not exist...

// old:
print(AppDefaults.integer(forKey: "Test")) // == 0
// new:
print(AppDefaults.integerOptional(forKey: "Test")) // == nil

в Swift3, я использовал таким образом

var hasAddedGeofencesAtleastOnce: Bool {
    get {
        return UserDefaults.standard.object(forKey: "hasAddedGeofencesAtleastOnce") != nil
    }
}

на ответ отлично, если вы будете использовать это несколько раз.

надеюсь, это поможет :)

Swift 3.0

if NSUserDefaults.standardUserDefaults().dictionaryRepresentation().contains({ .0 == "Your_Comparison_Key" }){
                    result = NSUserDefaults.standardUserDefaults().objectForKey(self.ticketDetail.ticket_id) as! String
                }