`NSUserDefaults` not saving float properly - ios

I am building an application in which I want to save some user data by using NSUserDefaults, and it is a property of one of my controllers as following:
#property (nonatomic, strong) NSUserDefaults *userPreference;
#synthesize userPreference = _userPreference;
And I am trying to save something called a scale that should be a float, so I do something like this in the getter to put in some default values of scale in case user did not enter one:
if (!_userPreference) {
_userPreference = [NSUserDefaults standardUserDefaults];
}
if (![_userPreference floatForKey:#"scale"]) {
// if user has not entered this info yet
// also 0 is not a valid value so I can do this
[_userPreference setFloat:100.0 forKey:#"scale"]; // let default scale be 100.0
[_userPreference synchronize];
}
However, when I later on query this, no matter what I set in the default value, the following command:
[self.userPreference floatForKey:#"scale"];
always return 1. I am not sure what is happening. Am I not creating the NSUserDefaults correctly?
Thank you in advance!

if you want to use NSUserDefaults, do not create any variables or #propertys. Just use
[[NSUserDefaults standardUserDefaults] setFloat:forKey:]
[[NSUserDefaults standardUserDefaults] synchronize];
to save your data and
[[NSUserDefaults standardUserDefaults] floatForKey:]
for fetching data.

Store using
[_userPreference setObject:[NSNumber numberWithFloat:100.0] forKey:#"Scale"];
[_userPreference synchronize];
and retrieve it using
float value = [[_userPreference objectForKey:#"Scale"] floatValue];

Have you tried this to set the float value:
[_userPreference setObject:[NSNumber numberWithFloat:100.0f] forKey#"scale"];
and the following to retrieve:
CGFloat scale = [[_userPreference objectForKey#"scale"] floatValue];

Change your if condition to this:
if ([_userPreference floatForKey:#"scale"] == 0.0f ) {
NSUserDefaults will always return 0.0f if no value is set for the key. Since you are saying that "also 0 is not a valid", you can safely use this approach

try this
-(void) saveFloatToUserDefaults:(float)x forKey:(NSString *)key {
NSUserDefaults * userDefaults = [NSUserDefaults standardUserDefaults];
[userDefaults setFloat:x forKey:key];
[userDefaults synchronize];
}
-(float) retriveFromUserDefaultsForKey:(NSString *)key {
NSUserDefaults * userDefaults = [NSUserDefaults standardUserDefaults];
return [userDefaults floatForKey:key];
}
[self saveFloatToUserDefaults:6.55 forKey:#"myFloat"];
float x = [self retriveFromUserDefaultsForKey:#"myFloat"];

Related

UILabel text not being stored in NSUserDefault

I have a UILabel called 'labelA'. In this label is the letter 'A'.
When I am using NSUserDefault and start my app, the label is empty, but I don't know why?
Here is my ViewController.m file:
- (void)viewDidLoad {
NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
self->labelA.text = [defaults objectForKey:#"labelAtext"]; }
- (void)defaults {
NSString *textLabelA = labelA.text;
NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:textLabelA forKey:#"labelAtext"];
[defaults synchronize];
}
Here is my NSString in the ViewController.h file
NSString *textLabelA =#"A";
When i load my app without NSUserDefault the labelA.text = A.
does anybody know what's my problem. Thanks a lot :-)
Your method defaults is not being called anywhere, so the text value is never stored in NSUserDefaults.
[self defaults]; // This needs to be called somewhere before you try and access NSUserDefaults.
You should also be accessing self using dot notation, not ->
self.labelA.text = [defaults objectForKey:#"labelAText"];
-> is for dereferencing a struct in C, for more information - What is "->" in Objective C?
When you use UserDefaults. You should first test if you get a value as if the value doesnt exist you need to set it or not.
NSString * myPreference = #"labelAtext";
- (void)viewDidLoad {
NSUserDefaults* userDefault = [NSUserDefaults standardUserDefaults];
id labelValue = [userDefault objectForKey:myPreference];
if (labelValue) // if preference exist
self.labelA.text = labelValue; // set ur label
else
[self storeDefaultValue]; // you store a default value
}
- (void)storeDefaultValue
{
NSString *myDefaultValue = nil;
if ([self.labelA.text isNotEqualToString:#""]) // if ur label not empty
myDefaultValue = self.labelA.text;
else
myDefaultValue = #"Not Available"; // or whatever defaults value you want
NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:myDefaultValue forKey:myPreference];
[defaults synchronize];
}
What do you really want to achieve as I don't really understand whats the point of storing a value in preference as soon as you load your app. Give more details on what is your goal.

UIStepper - Set value from NSUserDefaults

I have the following code below which uses a stepper to set the value of the myLabel.
I have it set to store the value to NSUserDefaults.
1) I also need to set the stepper value to the same figure as that which I have put into the label. Can someone advise how to do this please? (I have added a comment to the code where I feel this should be.)
2) I would also like to check before loading the saveString that it is actually set, and if not, set a default value. Could you also advise how to achieve this?
Thanks.
- (void)viewWillAppear:(BOOL)animated
{
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSString *loadString = [defaults objectForKey:#"saveString"];
self.myLabel.text = loadString;
// Need to set the stepper value to that in loadString
}
- (IBAction)stepChanged:(id)sender {
NSString *saveString = [NSString stringWithFormat:#"%d",
[[NSNumber numberWithDouble:[(UIStepper *)sender value]] intValue]];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:saveString forKey:#"saveString"];
[defaults synchronize];
self.myLabel.text = saveString;
}
I have updated the code as follows:-
- (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];
}
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, something I just realised as I am typing this is 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.
Regarding question 1:
Just make one instance variable int stepper; (in your .h)
then in viewWillAppear set this variable as you do at the moment; and set
stepper = [defaults integerForKey:#"stepper"];
In your IBAction just call
stepper++;
self.myLabel.text = [NSString stringWithFormat:#"%i",stepper];
and save it in your NSUserDefaults.
Regarding question 2: NSUserDefaults offers the possibility to register defaults for certain keys, have a look at this:
NSDictionary *defaults = [NSDictionary dictionaryWithObjectsAndKeys:
#"test", #"key",
nil];
[[NSUserDefaults standardUserDefaults] registerDefaults:defaults];
If there is nothing set in the NSUserDefaults, the objectForKey method will return nil, so your loadString will be nil.
Now, you could convert the value you saved from a string into a number, something like [loadString floatValue];, but a probably better way would be to store an NSNumber into the userDefaults with the correct value, and recreate your label text with stringWithFormat method.

ios saving and retrieving NSNumber from NSUserdefaults

I've searched but I can't find a good explanation as to why I'm still not getting the right value from my saved Integer.
This is how I saved my event Id.
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
[prefs setInteger:eventSelected.eventId forKey:#"currentEvent"];
This is how I'm trying to retrieve it.
NSLog(#"user dfault %#", [NSNumber numberWithUnsignedInt:[[[NSUserDefaults standardUserDefaults] objectForKey:#"currentEvent"] unsignedIntegerValue]]);
I'm gettin gthis.
user dfault 123581200
Also, to note, event if I did intValue instead of unsignedIntegerValue , it would still give me a random id number. was wondering what I'm doing wrong.
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
// Convert your value to IntegerValue and Save it
[prefs setInteger:[eventSelected.eventId integerValue] forKey:#"currentEvent"];
// Dont forget to synchronize UserDefaults
[prefs synchronize];
// To Access this value
NSLog(#"%d",[prefs integerForKey:#"currentEvent"]);
Instead of this code NSLog(#"user dfault %#", [NSNumber numberWithUnsignedInt:[[[NSUserDefaults standardUserDefaults] objectForKey:#"currentEvent"] unsignedIntegerValue]]);
Use this
NSLog(#"user dfault %#", [[NSUserDefaults standardUserDefaults] integerForKey:#"currentEvent"]);
NSNumber give a pointer value, not integer value.
To retrieve the integer you should use below function:
[[NSUserDefaults standardUserDefaults] integerForKey:#"currentEvent"];
when you ask for objectForKey, it box it first and then return the object. Posting intValue will convert the address of that object into integer. Hence each time you will receive different number.
NSNumber *number;
store:
[[NSUserDefaults standardUserDefaults] setValue:number forKey:#"Number"];
retrieving:
number = [NSNumber numberWithInteger:[[NSUserDefaults standardUserDefaults] integerForKey:#"Number"]];

How to add to a saved NSUserDefault?

I am making a game in Xcode which in includes a scoring system in each level. Here I have some code that gets an NSString (passedValue1) by using a delegate.
Then i add the code to receive the value in my viewDidLoad and display my value in a UILabel
-(void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib
// Do any additional setup after loading the view, typically from a nib
NSString *key=#"labelKey";
if(passedValue1){
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
NSObject * object = [prefs valueForKey:key];
if(object != nil){
NSUserDefaults *defults = [NSUserDefaults standardUserDefaults];
[defults setValue:passedValue1 forKey:key];
[defults synchronize];
}
else{
NSUserDefaults *defults = [NSUserDefaults standardUserDefaults];
NSInteger readScore=[[[NSUserDefaults standardUserDefaults] valueForKey:key] integerValue];
NSInteger newValue=readScore+[passedValue1 integerValue];
[defults setValue:[NSString stringWithFormat:#"%d",newValue] forKey:key];
[defults synchronize];
}
}
label.text = [[NSUserDefaults standardUserDefaults]objectForKey:key];
}
Once I have displayed the value I then save it into a label using a NSUserDefault. However, once I have replayed my game and have another score value I would like to add the new passedValue1 value to the currently saved value...
For example:
say I play my level and I get the score value of 10. The value is then saved and I replay my level. I would then like to take the saved value and add it to the value i just scored. So thats say the second value I have scored is 20. I would then like my code to add them together and give me a value of 30.
can anyone help because the code I'm using does not correctly do the function that I want to do which is add the previous and the currently passed value.
What is wrong with my code??
Thanks in advance.
You shouldn't use valueForKey: for this (it's not what you might think it is, see Key-Value Coding). Instead, you should use objectForKey: or in your case integerForKey:.
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSInteger value = [defaults integerForKey:key];
value += [passedValue1 integerValue];
[defaults setInteger:value forKey:key];
BOOL success = [defaults synchronize];
It seems that you got your if condition wrong, it should be
if (object == nil) { // <-- you have object != nil here !
// save new value
} else {
// read old value, add something, save new value
}

how to store slider values in ios

Hi I am using uislider and get the values in label. now i try to save the slider values. I don't know how to do this. If anybody knows please share the code. This is my code for slider changed.
-(IBAction)sliderChanged:(id)sender
{
UISlider *slider = (UISlider *)sender;
if((int)slider.value % 10 == 0)
{
sliderLabel.text = [[NSString alloc] initWithFormat:#"Value of:%d", (int)slider.value];
}
}
You can use NSUserDefault for storing the slider value.
NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:sliderLabel.text forKey:#"Slider"];
[defaults synchronize];
You can retrieve the data like:
NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
NSString *strValue = [defaults objectForKey:#"Slider"];
myLabel.text = strValue != nil ? strValue : #"No Value";
The above code is saving the sliderLabel to the NSUserDefault. If you want to store the slider value in the form of float then use:
[defaults setObject:[NSNumber numberWithFloat:slider.value] forKey:#"Slider"];
Retreive it like:
NSNumber *strValue = [defaults objectForKey:#"Slider"];
NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:[NSNumber numberWithFloat:slider.value] forKey:#"sliderValue"];
I believe you should store the value as a float (the original type for a UISlider value), it's just cleaner, and you'll probably want to reuse the float value to set back your slider when reopening the screen with something like:
NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
[self.slider setValue:[[defaults objectForKey#"sliderValue"] floatValue]];

Resources