Creating a primary key with NSUserDefaults - objective-c

Im using the code below to create a unique i.d. for primary keys or where every I need them in a program. The code works and there is never any errors but sometimes during debugging I noticed that it does not always increment still with no errors.
Can the code be improved for reliability?
- (NSString*)createUniqueID
{
//create a unique ID
int currentID = [[[NSUserDefaults standardUserDefaults] valueForKey:#"kUniqueID"] intValue];
currentID++;
NSString *returnID = [NSString stringWithFormat:#"%i", currentID];
[[NSUserDefaults standardUserDefaults] setValue:returnID forKey:#"kUniqueID"];
[[NSUserDefaults standardUserDefaults] synchronize]; //added sync
return returnID;
}

seems you need to call synchronize function
[[NSUserDefaults standardUserDefaults] synchronize];

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

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.

save and load highscore

i tried to use NSUserDefults to save and load a highscore(nsinteger) for my game.
i created an void function that check if the gameoverscore is bigger than my highscore and if it does to switch between them. i want that every time the game is over there will be a label which show my currect highscore.
to do this, i create a property for my NSUsweDefults, in my viewdidload i tried to load the currect highscore, and another function (checkIfHighscore).
here is my NSUserDefults property:
#property(readwrite) NSUserDefaults *prefs;
here is my viewdidload code:
NSInteger currectHighscore = [prefs integerForKey:#"highscore"];
highScoreLabel.text = [NSString stringWithFormat:#"%d",currectHighscore];
here is my checkIfHighscore:
-(void)checkIfHighScore
{
if(gameOverScore > highScore)
{
highScore = gameOverScore;
[self newHighscoreAnimation];
[prefs setInteger:highScore forKey:#"highscore"];
[prefs synchronize];
}
highScoreLabel.text = [NSString stringWithFormat:#"Highscore: %d", highScore];
}
when i enter to this viewcontroller my highscorelabel shows 0, like it doesnt save my highscore.
what do i do wrong?
thanks!
// Snippet used to save your highscore in the prefs.
int highScore = yourGameScore;
[[NSUserDefaults standardUserDefaults] setObject:[NSNumber numberWithInt:highScore] forKey:#"HighScore"];
[[NSUserDefaults standardUserDefaults] synchronize];
// Snippet used to get your highscore from the prefs.
highScore = [[[NSUserDefaults standardUserDefaults] objectForKey:#"HighScore"] intValue ];

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];

How to check if the app is starting for the first time?

I'm working on a new version of an app. In older version of the app some content has been downloaded from the web into the Cache-folder. This content is no longer valid in the new version, so I would like to delete some of these files first time this the new version of the app starts.
How can I check that the app is starting for the first time? I could use NSUserDefaults to store an indication, but is there a better way to do this?
What I do is I check if the application has launched for the first time in didFinishLaunchingWithOptions: method, and I store the current version of the application in the defaults.
What this does is at every update of the application, I can keep a track of what files need to be removed, and what files need to be stored for that version of the application.
Following is the code for that:
if (![[NSUserDefaults standardUserDefaults] boolForKey:kNOT_FIRST_LAUNCH]) {
NSLog(#"fresh install = %d", (int)[self checkForFreshInstall]);
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:kAPPLICATION_LAUNCHING_FIRST_TIME];
[[NSUserDefaults standardUserDefaults] synchronize];
} else {
[[NSUserDefaults standardUserDefaults] setBool:NO forKey:kAPPLICATION_LAUNCHING_FIRST_TIME];
[[NSUserDefaults standardUserDefaults] synchronize];
}
This is the checkForFreshIntallMethod:
- (BOOL) checkForFreshInstall {
NSString *currentVersion = (NSString*)[[NSBundle mainBundle] objectForInfoDictionaryKey:#"CFBundleVersion"];
NSString *prevVersion = (NSString *)[[NSUserDefaults standardUserDefaults] valueForKey:#"prevVersion"];
if (prevVersion == nil) {
// Starting up for first time with NO pre-existing installs (e.g., fresh
// install of some version)
[[NSUserDefaults standardUserDefaults] setValue:currentVersion forKey:#"prevVersion"];
// Save changes to disk
[[NSUserDefaults standardUserDefaults] synchronize];
return YES;
}
else if ([prevVersion intValue] < [currentVersion intValue]) {
// Starting up for first time with this version of the app. This
// means a different version of the app was alread installed once
// and started.
[[NSUserDefaults standardUserDefaults] setValue:currentVersion forKey:#"prevVersion"];
// Save changes to disk
[[NSUserDefaults standardUserDefaults] synchronize];
return NO;
}
return YES;
}
Let me know if you have any questions.
There is nothing wrong with the NSUserDefaults approach.
if(the flag has not been set somewhere to say we've already done this dance){
do the stuff we need to do
set the flag that we'll check again next time and skip this code next time
}