2

I want to check if a float stored in NSUserDefaults is pre-existing. The Apple documentation suggests that it floatForKey will return 0 if the key does not exist.

How do I correctly tell the difference between a stored 0 and a non-existent key?

Rishil Patel
  • 1,977
  • 3
  • 14
  • 30
djskinner
  • 8,035
  • 4
  • 49
  • 72
  • 1
    Here is one similar post : [CLICK HERE][1] [1]: http://stackoverflow.com/questions/5397364/iphone-how-to-detect-if-a-key-exists-in-nsuserdefaults-standarduserdefaults – Guru Aug 27 '12 at 17:33

3 Answers3

12

A reliable way to see if a default has been set is:

if (![[NSUserDefaults standardUserDefaults] valueForKey:@"foo"]) { ... }

This works regardless of the data type.

woz
  • 10,888
  • 3
  • 34
  • 64
  • Cheers woz, this is what worked best in the end and solved my immediate issue. Will probably look at implementing Raj's suggestion at some point too. – djskinner Aug 28 '12 at 20:15
0

If the objectForKey is nil, no object exists, so there is no item stored in NSUserDefaults.

Bernd Rabe
  • 790
  • 6
  • 23
0

Thanks to woz and Bernd Rabe. My solution is this:

    //Set volume
    id savedVolume = [[NSUserDefaults standardUserDefaults] objectForKey:@"GameVolume"];
    if (savedVolume == nil) //Check if volume not already saved (e.g. new install)
    {
        //Set default volume to 1.0
        float defaultVolume = 1.0;
        [[ApplicationController controller].soundManager setGlobalVolume: defaultVolume];
        [[NSUserDefaults standardUserDefaults] setFloat:defaultVolume forKey:@"GameVolume"];
    } else {
        float savedVolume = [[NSUserDefaults standardUserDefaults] floatForKey:@"GameVolume"];
        [[ApplicationController controller].soundManager setGlobalVolume: savedVolume];
    }

Does that look safe enough?

djskinner
  • 8,035
  • 4
  • 49
  • 72
  • The way I do it always works, and it's less code. Also, I generally try to avoid using `id` for a variable. If you inadvertently checked a default that was a `BOOL` using your method, you would have a problem. – woz Aug 27 '12 at 17:40
  • Actually, `id` is only for object pointers, so I am surprised that it work for you using `float`, which is a native type. Did you test it? – woz Aug 27 '12 at 17:44
  • Not tested to be honest but yeah - if that did return a float then it couldn't possibly be nil. Will test when I get chance but actually it looks like Raj's solution is the best way forwards. – djskinner Aug 27 '12 at 18:48
  • I think the point of this is for you to mark the answer that helped you as correct. Not write in the end result that you got from the existing answers. – Mick MacCallum Aug 27 '12 at 19:12
  • Raj's solution is great. One caveat though: You will have to convert your `float` to an `NSNumber` before registering it. – woz Aug 27 '12 at 20:02