0

The functionality I'm trying to get to is to default the state of my switch to setOn:YES but once the user toggles the UISwitch save the state of that switch in NSUserDefaults.

How would I best go about this in my view? I currently have the code below in my viewDidLoad:

if([[NSUserDefaults standardUserDefaults] boolForKey:@"lights"] == 0){
        [lightsSwitch setOn:NO];
}

and in my toggleLightSwitch:(id)sender:

[[NSUserDefaults standardUserDefaults] setBool:lightsSwitch.isOn
                                            forKey:@"lights"];

but the functionality will be to default to setOn:NO. Since NSUserDefault defaults to NO for a bool key, is there a way I can fix this?

iDev
  • 1,042
  • 13
  • 19
locoboy
  • 38,002
  • 70
  • 184
  • 260

4 Answers4

7

NSUserDefaults starts empty, so asking for a key returns nil, and calling -boolValue on nil returns NO/0

You should use -[NSUserDefaults registerDefaults:] to set defaults for your keys/values in -appDidFinishLaunching in your app delegate:

-(void)applicationDidFinishLaunching:(UIApplication*)app
{
    NSDictionary * defaults = @{
        "lights" : @YES
        // you can list the default values for other defaults/switches here
    } ;
    [ [ NSUserDefaults standardUserDefaults ] registerDefaults:defaults ] ;
}

In your -viewDidLoad, do this:

lightsSwitch.on = [ [ NSUserDefaults standardUserDefaults ] boolForKey:@"lights" ] ;

In your toggleLightSwitch, I would to this:

BOOL isOn = [ [ NSUserDefaults standardUserDefaults ] boolForKey:@"lights" ] ;
isOn = !isOn ; // toggle ;
[ NSUserDefaults standardUserDefaults ] setBool:isOn ForKey:@"lights" ] ;
self.lightsSwitch.on = isOn ;
nielsbot
  • 15,922
  • 4
  • 48
  • 73
  • won't `didFinishLaunching` fire every app launch though? This would automatically reset the switch every time? – locoboy Oct 29 '13 at 07:34
  • no--registerDefaults only sets the original defaults. it doesn't replace any values already set. see the docs: https://developer.apple.com/library/ios/documentation/cocoa/reference/foundation/Classes/NSUserDefaults_Class/Reference/Reference.html#//apple_ref/doc/uid/20000318-CIHDDCDB – nielsbot Oct 29 '13 at 07:36
  • alright let me try. is this the most scalable solution for lets say 10 switches also? – locoboy Oct 29 '13 at 07:36
  • this looks good. only question is do I have to do this 10x :P? – locoboy Oct 29 '13 at 07:48
  • No.. let's say your switches are controlled by defaults "lights", "camera", "action", change the dictionary above to be `@{ "lights":@YES, "camera":@YES, @"action":@YES }` for example – nielsbot Oct 29 '13 at 08:18
  • Or maybe it's just an array: `@{ "lights":@[ @YES, @YES, @YES, @YES, ..., @YES ]}`. Then you use it like (for switch #3): `switch.on = [ [ [ [ NSUserDefaults standardUserDefaults ] objectForKey:@"lights" ] objectAtIndex:3 ] boolValue ]` – nielsbot Oct 29 '13 at 08:20
0

If the default state is 'YES', you can set NSUserDefualt value to YES when the app run at the first time, or you can use an enum value, with an extra value saying the value hasn't been set yet.

Avi Tsadok
  • 1,843
  • 13
  • 19
0

You set in Yes to lights in didFinishLaunchingWithOptions method, for checking that app is running first time.

  if ([[NSUserDefaults standardUserDefaults]objectForKey:@"lights"]==nil)
    {
        [[NSUserDefaults standardUserDefaults]setBool:YES forKey:@"lights"];
    }
Toseef Khilji
  • 17,192
  • 12
  • 80
  • 121
  • 1
    It's probably better to use `[NSUserDefaults registerDefaults:]`. That's explicitly for setting default values for your defaults. – nielsbot Oct 29 '13 at 07:29
  • This makes the most sense to me right now - but how scalable is this if I have 10 switches? – locoboy Oct 29 '13 at 07:32
0

First You should set the boolValue to YES in your NSUserDefaults for @"lights" key and then use if to check if the value is YES then set the UISwitch value to YES or No depending the boolValue in NSUserDefaults.

in didFinishLaunchingWithOptions: write

NSDictionary *defaults = [NSDictionary dictionaryWithObjectsAndKeys:YES, @"lights", nil];

  [[NSUserDefaults standardUserDefaults] registerDefaults:defaults];

in your -viewDidLoad method write

UISwitch *mySwitch = [[UISwitch alloc] initWithFrame:CGRectZero];
mySwitch.on = [[NSUserDefaults standardUserDefaults] boolForKey:@"lights"];;
[mySwitch addTarget:self action:@selector(toggleLightSwitch:)forControlEvents:UIControlEventValueChanged];

and in your toggles method check the value and set the appropriate value in NSUserDefaults

 -(void)toggleLightSwitch:(id)sender {

    if (!sender.on) {

        [[NSUserDefaults standardUserDefaults] setBool:NO forKey:@"lights"]; 
    }
    else
    {
        [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"lights"];

    }
}
Suhit Patil
  • 11,748
  • 3
  • 50
  • 60