0

I have the following code. However, the line

stepper.value = [NSNumber numberWithDouble:loadNumber];

errors with the error 'Sending NSNumber *__strong to a parameter of incompatible type 'double''. I think the stepper will only accept a double, but am unsure what I am doing wrong to set it.

What I need to achieve is the following:-

1) Have a default value set in NSUserDefaults for saveNumber, which will be used until a variation is made by the user.

2) on load or view appearing, use saveNumber to set the value of both stepper.value and myLabel.

3) ensure that when changed with the stepper, the value is updated in myLabel, and NSUserDefaults saveNumber is also updated.

Can anyone advise where I am going wrong, and help correct my code please?

Further,I just realised that in the final app, I will have this setting on a different viewController to the one that will use the NSUserDefaults savedNumber value. With this in mind, can you also let me know how to ensure that savedNumber is available not only to this viewController, but any other one I require the values on?

Many thanks.

- (void)viewWillAppear:(BOOL)animated
{
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    NSNumber *loadNumber = [defaults objectForKey:@"saveNumber"];
    self.myLabel.text = [NSString stringWithFormat:@"%@",loadNumber];
    UIStepper *stepper = [[UIStepper alloc] init];
    stepper.value = [NSNumber numberWithDouble:loadNumber];
}

- (IBAction)stepChanged:(id)sender {
    NSNumber *saveNumber = [NSNumber numberWithDouble:[(UIStepper *)sender value]];
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    [defaults setObject:saveNumber forKey:@"saveNumber"];
    [defaults synchronize];
    self.myLabel.text = [NSString stringWithFormat:@"%@",saveNumber];
}

I have one outstanding issue which is that I cannot get the defaults to deliver if no value has been set!

I have the following code in AppDelegate.m:-

    NSDictionary *defaults = @{ @"saveNumber": @8 };
    [[NSUserDefaults standardUserDefaults] registerDefaults:defaults];

When the App first launches (and every time after until the stepper has been used) the value being seen is 'null'.

Any ideas?

NeilMortonNet
  • 1,500
  • 4
  • 16
  • 36
  • why do you make a new thread ? also in the other thread i already suggested you to change stepper.value – dehlen Dec 21 '13 at 00:00
  • @dehlen I wasn't sure of the right way to manage the threads. Now I know I could have just carried on with the other. I changed the stepper.value as you say, and this works to populate the value. My one outstanding issue is that I cannot get the defaults to deliver if no value has been set! Any ideas much appreciated. – NeilMortonNet Dec 21 '13 at 11:44
  • OK. I just shifted the registerDefaults onto the viewController.m file and it worked. So looked back at the appDelegate.m and realised I had placed the two lines AFTER the return YES statement, and thus it was never being called. Thank you all. – NeilMortonNet Dec 21 '13 at 15:24

1 Answers1

2

This:

stepper.value = [NSNumber numberWithDouble:loadNumber];

needs to be:

stepper.value = [loadNumber doubleValue];

And you don't need to call synchronize after setting the value in NSUserDefaults.

A value stored in NSUserDefaults can be accessed from any class, not just the class that sets it.

Update:

To set a default value you want the following:

NSDictionary *defaults = @{ @"saveNumber": @6 };
[[NSUserDefaults standardUserDefaults] registerDefaults:defaults];

This will set a default value of 6 for @"saveNumber".

rmaddy
  • 314,917
  • 42
  • 532
  • 579
  • Thank you for this. I had been staring at it for ages! how do i set a default value? as right now the code breaks out as a nil value until used? – NeilMortonNet Dec 20 '13 at 16:48
  • Not calling `synchronize` is somewhat dangerous, especially in iOS7, where killing the app quickly is possible and very likely. The system is supposed to call `synchronize` when the app goes inactive and to background, but sometimes we've seen data is not saved unless we call it directly. – Léo Natan Dec 20 '13 at 16:50
  • Thanks for the heads up on that. I had seen a comment along the similar lines that if the app wasn't exited correctly the data may not save without it. I am still stuck with how to set a default value in NSUserDefaults for saveNumber, which will be used until an initial variation is made by the user? Right now the code pauses as it is showing as loadValue / saveValue is showing as nul. – NeilMortonNet Dec 20 '13 at 16:53
  • @LeoNatan If you want to call `synchronize`, call it in the app delegate's `didEnterBackground` method. No need to call it all over the app. – rmaddy Dec 20 '13 at 16:53
  • We did that already and we still had some trouble. BTW, in the scenario I mentioned above, `didEnterBackground` is not called. – Léo Natan Dec 20 '13 at 16:55
  • @MrNeilM Use `NSUserDefaults registerDefaults:` to register default values. Call this in your app delegate `application:didFinishLaunchingWithOptions:` method. – rmaddy Dec 20 '13 at 16:55
  • @rmaddy what would the syntax be for this? if I wanted to set saveNumber to say 6? Obviously need it to be a double too? – NeilMortonNet Dec 20 '13 at 17:08
  • @Rmaddy I still get a nil value on initial load? Also, it doesn't appear that the value of the stepper is being set. Whilst the label shows the correct figure, the stepper starts from whatever is configured on the stepper in storyboard. – NeilMortonNet Dec 20 '13 at 17:26
  • Why are you creating a new stepper that you never use? Do you have an outlet for the stepper? Use that outlet instead of creating a new instance. – rmaddy Dec 20 '13 at 17:55
  • I do have an outlet for the stepper, named stepper! I have just removed "UIStepper *stepper = [[UIStepper alloc] init];" and now the code does allow the latest value to be passed and work. However, the defaults value is not being passed in. The code shows null value still on initial launch (or any launch until the stepper has been pressed). Any ideas? – NeilMortonNet Dec 20 '13 at 18:51
  • @rmaddy I do have an outlet for the stepper, named stepper! I have just removed "UIStepper *stepper = [[UIStepper alloc] init];" and now the code does allow the latest value to be passed and work. However, the defaults value is not being passed in. The code shows null value still on initial launch (or any launch until the stepper has been pressed). Any ideas? – NeilMortonNet Dec 20 '13 at 22:56
  • Just added some extra info into thread. Please can someone advise? – NeilMortonNet Dec 21 '13 at 15:10
  • @rmaddy OK. I just shifted the registerDefaults onto the viewController.m file and it worked. So looked back at the appDelegate.m and realised I had placed the two lines AFTER the return YES statement, and thus it was never being called. Thank you for your help. – NeilMortonNet Dec 21 '13 at 15:25