App is crashing on NSUserDefaults setObject:forKey: - objective-c

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

Related

NSUserDefaults setObject not saving for first time

My application saving NSData (contains bookmarked file reference) list to NSUserDefaults in somewhat following way, at any point of application process:
NSMutableArray *bookmarkedURLs = [[NSMutableArray alloc] init];
[bookmarkedURLs addObject:bookmark]; // 'bookmark' is a NSData object
[[NSUserDefaults standardUserDefaults] setObject:bookmarkedURLs forKey:#"AppBookmarks"];
[[NSUserDefaults standardUserDefaults] synchronize];
When application starts I checked through NSUserDefaults to populate saved NSData list:
bookmarkedURLs = [[[NSUserDefaults standardUserDefaults] objectForKey:#"AppBookmarks"] mutableCopy];
if (bookmarkedURLs.count == 0)
{
bookmarkedURLs = [[NSMutableArray alloc] init];
NSLog(#"INITIALIZED");
}
else
{
NSLog(#"STORES NSDATA LIST");
....
}
The problem I faced I can order in following steps:
There is no saved NSUserDefaults data by 'AppBookmarks' key
Save a NSData to NSUserDefaults by 'AppBookmarks' key
Restarts application
Application tries to populate a NSMutableArray from NSUserDefaults' 'AppBookmarks' key but always found 0 records
I save again a new NSData to 'AppBookmarks' key
Restarts application
Application tries to populate NSMutableArray from 'AppBookmarks' and this time it found saved record(s).
Any restart of application or new NSData addition to 'AppBookmarks' never fails thereafter
So whenever there is no saved data to NSUserDefaults and I saved a value, it's not loading or saving for first time. Any attempt to save and load is working after then.
Try this:
NSMutableArray *bookmarkedURLs = [[NSMutableArray alloc] init];
[bookmarkedURLs addObject:bookmark]; // 'bookmark' is a NSURL object
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:bookmarkedURLs forKey:#"AppBookmarks"];
[defaults synchronize];
I hope this can help you.
You can do something like,
NSUserDefaults *myDefaults = [NSUserDefaults standardUserDefaults];
// for example
NSURL *url1; // your url1
NSURL *url2; // your url2
//Set data to userdefaults
NSMutableArray *arr = [[NSMutableArray alloc]initWithObjects:url1,url2, nil]; // Store urls directly in array
NSData *bookMarkdata = [NSKeyedArchiver archivedDataWithRootObject:arr]; // convert whole array in data
[myDefaults setObject:bookMarkdata forKey:#"AppBookmarks"]; // save that data object to userdefaults
[myDefaults synchronize];
//Retreive data from userdefaults
NSData *resultData = [myDefaults objectForKey:#"AppBookmarks"]; //retrieve data from user defaults
NSMutableArray *resultArr = [NSKeyedUnarchiver unarchiveObjectWithData:resultData]; // get result array from data

Possible to persist HKQueryAnchor in NSUserDefaults?

So I'm a bit dismayed that Apple has replaced a transparent, easy-to-handle NSUInteger with an HKQueryAnchor but has not provided an easy way to persist that HKQueryAnchor. Has anyone found a good way to do this with NSUserDefaults? The only persistence method I have seen is an archiver to a local file, but my app persists everything in NSUserDefaults, and I'd like to keep it that way if possible. Is there a reliable way to store an HKQueryAnchor this way?
You can convert it to NSData using NSKeyedArchiver and store that in the user defaults.
To store:
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:anchor];
[[NSUserDefaults standardUserDefaults] setObject:data forKey:#"AnchorData"];
To retrieve:
NSData *data = [[NSUserDefaults standardUserDefaults] objectForKey:#"AnchorData"];
HKQueryAnchor *anchor = [NSKeyedUnarchiver unarchiveObjectWithData:data];

Setting value in nsuserdefaults

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.

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.