Setting value in nsuserdefaults - objective-c

I'm new to Objective-C and XCode and I've encountered such a problem.
How do you properly save the value to NSUserDefaults.
I have value in
[_textFields objectAtIndex:2]).text
And trying to do this
[[[NSUserDefaults standardUserDefaults] setValue:((UITextField *)[_textFields objectAtIndex:2]).text)) forKey:#"Phone"];
[[NSUserDefaults standardUserDefaults] synchronize];
How do you do it properly?

Use setObject:forKey: instead of setValue:forKey:
[[[NSUserDefaults standardUserDefaults] setObject:((UITextField *)[_textFields objectAtIndex:2]).text)) forKey:#"Phone"];
Update:
You code will work if you really have that text field in the array. Here is the step by step broken down code to make it more clear:
UITextField* textField = [_textFields objectAtIndex:2]; // get your text field
NSString* text = textField.text; // get the actual value we are going to store
[[[NSUserDefaults standardUserDefaults] setObject:text forKey:#"Phone"]; // store it

You are working with strings values. You should use setObjectForKey (save) and objectForKey (read). Here's an example
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
NSString *yourText = [[_textFields objectAtIndex:2] text]; // Your text
// Save
[userDefaults setObject:yourText forKey:kKey];
[userDefaults synchronize];
// Read
NSString *result = (NSString *) [userDefaults objectForKey:kKey];

Use method setObject:forKey: instead of setValue:forKey:
In NSUserDefaults class:
[[NSUserDefaults standardUserDefaults] setObject:"Your Object" forKey:#"Phone"];

You need to use the setObject:forKey: if you want to store property list objects (dictionaries, arrays, strings and numbers) in NSUserDefaults. See the docs.

Related

App is crashing on NSUserDefaults setObject:forKey:

While setting object to NSUserDefaults my App is crashing Randomly in iOS 12.Below is my code where the crash occurs
shared2 = [[NSUserDefaults alloc]initWithSuiteName:#"group.AppName"];
NSData *datashare = [NSKeyedArchiver archivedDataWithRootObject:_sharedData];
[shared2 setObject:datashare forKey:#"dicForToday"];
Not getting any crash logs as it happens randomly
Frequency of this crash is much more on iOS 12.
Normally you can use this method for save data
Post Method:
[[NSUserDefaults standardUserDefaults] setObject:object forKey:#"somename"];
Get Method:
NSMutableDictionary *dicCover = [[NSUserDefaults standardUserDefaults] valueForKey:#"somename"];
some time ,dictionary or array or not formatting right way we can use to achive your data like this to use NSUserdefault
Use Achive:
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:arrayUsers];
[[NSUserDefaults standardUserDefaults] setObject:data forKey:#"somename"];
To get:
NSData *usersData = [[NSUserDefaults standardUserDefaults] valueForKey:#"somename"];
NSMutableArray *redirectionDic = [NSKeyedUnarchiver unarchiveObjectWithData:usersData];
NSUserDefaults *myDefaults = [[NSUserDefaults alloc]
initWithSuiteName:keyChainGroup];
[myDefaults setObject:userInfo forKey:key];
Try this

NSUserDefaults write string and clean it after

I write a string in NSUserDefaults
[[NSUserDefaults standardUserDefaults] setObject: myString forKey: # "String"];
Then I take out this string from NSUserDefaults and return
- (NSString *) retrieveString
{
     NSString * recoveredString = [[NSUserDefaults standardUserDefaults] objectForKey: # "String"];
     return recoveredString;
}
Then in viewDidLoad write the returned string in another string
NSString * filePath = [self retrieveString];
I need to delete a string of NSUserDefaults after I was returning to her in - (NSString *) retrievestring
I do so
- (NSString *) retrieveString
{
     NSString * recoveredString = [[NSUserDefaults standardUserDefaults] objectForKey: # "String"];
[[NSUserDefaults standardUserDefaults] removeObjectForKey: # "String"];
     return recoveredString;
}
But this does not work, the line is not deleted.
How to fix it
Thanks to all.
NSUserDefaults updates its data periodically only, not each and every time a setter or getter is called. If you want an immediate update, call
[[NSUserDefaults standardUserDefaults] synchronize];
You need to add the synchronize call AND move your return call (so it is the last line in the method). So, your code should like this:
- (NSString *) retrieveString
{
NSString * recoveredString = [NSString stringWithString:[[NSUserDefaults standardUserDefaults] objectForKey: # "String"]];
[[NSUserDefaults standardUserDefaults] removeObjectForKey: # "String"];
[[NSUserDefaults standardUserDefaults] synchronize];
return recoveredString;
}

How to Read String from NSUserDefaults

I have an object at the root of plist that stores objects and keys (one of which is input from a user textfield). I have no problem writing and creating structure; it's trying to read values that causing problem. Below code I used to write the data, can someone tell me how to read the string [val] and [myKey]?
thank you!
#define defaultValue #"Your Name"
#define myKey #"PersonName"
- (void)textFieldAction:(id)sender {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSString *val;
// Get the new value from the textfield
val = [myTextField stringValue];
if ([val isEqualToString:defaultValue]) {
[defaults removeObjectForKey:myKey];
} else {
// [defaults setObject:val forKey:myKey];
NSDictionary *my_dict = [NSDictionary dictionaryWithObjectsAndKeys:
#"Name", #"PersonName",
#"Email", #"PersonEmail",
#"Dept", #"PersonDept",
#"Job", #"PersonJob",
val, myKey,
#"Status", #"PersonStatus",
nil];
[defaults setObject: my_dict forKey: #"Person"];
[[NSUserDefaults standardUserDefaults] registerDefaults:my_dict];
I would like to automatically populate the textfield with the [val], for [myKey], if the user has the info already in the plist. Here's the code I'm trying to use for that:
- (void)applicationDidFinishLaunching:(NSNotification *)notification {
NSUserDefaults *defaults = [[NSUserDefaults standardUserDefaults] objectForKey:myKey];
NSString *val = [defaults stringForKey:myKey];
if (val == nil) val = defaultValue;
[myTextField setStringValue:val];
You can write the value into NSUserDefault like the following:
[[NSUserDefaults standardUserDefaults] setValue:[myTextField stringValue] forKey:#"Person"];
And read it later like the following:
[myTextField setStringValue:[[NSUserDefaults standardUserDefaults] stringForKey:#"Person"];
So you can simplify your code into:
- (void)textFieldAction:(id)sender {
[[NSUserDefaults standardUserDefaults] setValue:[myTextField stringValue] forKey:#"Person"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
You can set a default value with the registerDefaults:. And when you can retrieve that value simply by calling:
- (void)applicationDidFinishLaunching:(NSNotification *)notification
{
// ...
[[NSUserDefaults standardUserDefaults] registerDefaults:#{#"Person", defaultValue}]
NSString *value = [[NSUserDefaults standardUserDefaults] stringForKey:#"Person"];
[myTextField setStringValue:value];
// ...
}
If I understand correctly, you should be able to do what you need by simply doing:
NSString * val = [[NSUserDefaults standardUserDefaults] objectForKey: myKey];
[textfield setText: val];
NSUserDefaults Reference Page
myTextField.text = [[NSUSerDefaults standardUserDefaults] objectForKey:myKey];

AVAudioPlayer and NSUserDefaults

[PlaySound stop];
[PlaySound prepareToPlay];
[[NSUserDefaults standardUserDefaults] synchronize];
text = [[NSUserDefaults standardUserDefaults] stringForKey:#"defaulttext"];
NSLog(#"%#",text);
BOOL loop = [prefs boolForKey:#"switch"];
NSLog(#" %d",loop);
do {
[PlaySound play];
} while (loop ==YES);
There are two major problems I am facing with this code.
1) This is a function which is called when a button is tapped... I am allocating the audio player in this function. Whenever this function is called I called the stop function on audio player yet it does not stop and two sounds play simultaneously.
2) My defaults are not registering correctly. Both the string and bool are showing nil in console.
I haves added settings bundle in my app.
Edit: Rest of the method
NSUInteger selectedRow= [SoundPicker selectedRowInComponent:0];
NSString *userchoice =[self pickerView:SoundPicker titleForRow:selectedRow forComponent:0];
NSString *soundpath = [[NSBundle mainBundle] pathForResource:userchoice ofType:#"wav"];
NSURL *fileURl = [[NSURL alloc] initFileURLWithPath:soundpath];
NSError **error = nil;
PlayFartSound = [[AVAudioPlayer alloc] initWithContentsOfURL:fileURl error:error];
I have sorted the problem of audio player.
Can anyone please help on NSUserDefaults.
In my settings root plist I have a text field with identifier name name_preference so I put this in code:
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
text = [defaults stringForKey:#"name_preference"];
NSLog(#"%# abc",text);
The log is (null) abc ? [I have set the default value to hello in plist]
How are you setting the default values in your NSUserDefaults? You say you've got the defaults in a plist, but when do you load that plist into NSUserDefaults?
To set the default NSUserDefaults values, you need to call this somewhere early in your program, ideally in somewhere like applicationDidFinishLaunching
[[NSUserDefaults standardUserDefaults] registerDefaults:defaults];
Where 'defaults' is a dictionary of default settings, possibly loaded from a plist.

Saving NSRect to NSUserDefaults

Currently I'm trying to save an NSRect to my user defaults. Right now I'm using a NSValue to wrap it as an object then save it into the user defaults as an object with the following code
[userDefaults setObject:[NSValue valueWithRect:rect forKey:#"Key"]];
However, when I run it, I get an error that says [NSUserDefaults setObject:forKey:]: Attempt to insert non-property value 'NSRect: {{0, 0}, {50, 50}}' of class 'NSConcreteValue'.
Does anyone know how I can fix this? Thanks.
Here is a much simpler solution, using NSString:
// store:
[[NSUserDefaults standardUserDefaults]
setValue:NSStringFromCGRect(frame) forKey:#"frame"];
// retrieve:
CGRect frame = CGRectFromString(
[[NSUserDefaults standardUserDefaults] stringForKey:#"frame"]);
Swift 4
// store
UserDefaults.standard.set(NSStringFromCGRect(rect), forKey: "frame")
// retrieve
if let s = UserDefaults.standard.string(forKey: "frame") {
let frame = CGRectFromString(s)
}
NSValue is not supported by the user defaults.
The value parameter can be only property list objects: NSData,
NSString, NSNumber, NSDate, NSArray, or NSDictionary. For NSArray and
NSDictionary objects, their contents must be property list objects.
You need to archive the value into data then unarchive it when you access it.
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
NSRect rect = { 0, 0, 10, 20 };
NSValue *value = [NSValue valueWithRect:rect];
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:value];
[userDefaults setObject:data forKey:#"key"];
[userDefaults synchronize];
data = [userDefaults objectForKey:#"key"];
NSValue *unarchived = [NSKeyedUnarchiver unarchiveObjectWithData:data];
NSLog(#"%#", unarchived);