How I can make NSUserDefaults for each user of my app? - ios

I need make access to UserDefaults in my app. But I need save settings for each user, who was registered in app. For example:
[[NSUserDefaults standartUserDefaults] setObject:#"15:00" forKey:#"lastTime"]// for current user1
and after logout user1 and login user2:
[[NSUserDefaults standartUserDefaults] setObject:#"11:00" forKey:#"lastTime"]// for current user2
And, if I try read key #"lastTime", then I get the last value, but not for this user. I can store userDefaults in differentFiles, as an a variant? Or other solutions?
UPDATED:
Finally I solved this problem:
#define UserDefaults [NSUserDefaults standardUserDefaults]
#define uKey(key) [NSString stringWithFormat:#"%#_%#",key,User.user_name]
[UserDefaults setInteger:lastData forKey:uKey(#"lastResultDataId")];

There is no concept of users on iOS (yet). Each device, an iPhone or iPad, is presumed to have one and only one user. Obviously that's often not true, especially on an iPad, so some apps create schemes for different people to use the device. If you've done that -- and it's not clear that you have -- then you know the username. If you are writing a Mac app then use NSUserName() to get the name of the logged-in user. After that just concatenate the username onto the key from your NSUserDefaults, something like this:
NSString *username = #"john";
[[NSUserDefaults standardUserDefaults] setObject:#"15:00" forKey:[NSString stringWithFormat:#"last_login_username_%#", username]];
(username would set either to NSUserName() for a Mac app or whatever scheme you've come up for a multiuser iOS app)

If you have some kind of user identifier, use a dictionary for the different users:
NSDictionary *user = #{#"lastTime": #"15:00" };
[[NSUserDefaults standartUserDefaults] setObject:user forKey:#"userId"];

You have to have some way to uniquely identify the user, then just use whatever that is - UUID, username, email, userId - in the key when setting / getting the lastTime value

Personally I'd use a NSDictionary like and have a dictionary per user and store that into NSUserDefaults under a key constructed out of their username similar to below.
NSMutableDictionary *userDict = [[NSMutableDictionary alloc] init];
NSString *username = "myUsername";
NSDate *currentDateTime = [NSDate date];
[userDict setObject:username forKey:#"username"];
[userDict setObject:currentDateTime forKey:#"lastAccessed"];
/* Any other user date you want to store about this user
* Note we are going to use NSUserDefaults which is not
* secure so do not store sensitive data in here
*/
NSString *userDictKey = [NSString stringWithFormat:#"uk.co.yourAppName.%#", username];
[[NSUserDefaults standardUserDefaults] setObject:userDict forKey:userDictKey];
[[NSUserDefaults standartUserDefaults] synchronize];
And to retrieve this data all you'd need to do is know what the users username is and do
NSString *userDictKey = [NSString stringWithFormat:#"uk.co.yourAppName.%#", username];
NSDictionary *userRetrievedDict = [[NSUserDefaults standardUserDefaults] dictionaryForKey:userDictKey];
However if you want to make any amendments to this data you'll need to adapt it so that the data is moved into a NSMutableDictionary so you can update it and then store it back into NSUserDefaults

Make sure that after setting value, user going to synchronise the userdefaults.
like
[[NSUserDefaults standartUserDefaults] synchronize];

Related

How to save a high score

How do I go about saving a high score using nsuserdefaults and displaying it on the main menu. Currently my score label code looks like this. BTW I am using objective c.
_scoreLabel.text = [NSString stringWithFormat:#"%02lu", (unsigned long)_enemies.count];
this is how you save the score
if(HighScore<ScoreNumber)
{
[[NSUserDefaults standardUserDefaults]setInteger:ScoreNumber forKey:#"Save"];
}
this is how you get the score,so you need to convert int to string..and display a string in a label.
HighScore=[[NSUserDefaults standardUserDefaults] integerForKey:#"Save"];
You can save your highScore using NSUserDefaults setInteger. The code for saving an integer into NSUserDefault goes here.
[[NSUserDefaults standardUserDefaults] setInteger:HighScore forKey:#"HighScore"];
Now you can set the highScore from NSUserDefault. The code for retrieving Integer from NSUserDefault goes here.
[_scoreLabel setText:[NSString stringWithFormat:#"%d", [[NSUserDefaults standardUserDefaults] integerForKey:#"HighScore"]]];

How would I be able to save an integer when an app is terminated and then load it again once the app is reopened?

I am working on an app where I need to save one int until the player decides to play the game again. It would be greatly appreciated if someone could guide me by using NSUserDefaults to save this integer whenever the application is terminated, and then be able to load it again as soon as the application loads. If there is any further information that is needed to help you help me just let me know! Thanks in advance!
You cannot save an int, you will need to convert it to an NSNumber. Use:
NSNumber *number = #(myInt);
Then you can save it (when the app terminates in your appDelegate's applicationWillTerminate:) using:
[[NSUserDefaults standardUserDefaults] setObject:number forKey:#"number"];
[[NSUserDefaults standardUserDefaults] synchronize];
To retrieve the value use:
NSNumber *number = [[NSUserDefaults standardUserDefaults] stringForKey:#"number"];
As pranav told you can store int as NSNumber or you can store it as a String, Following will work fine with NSNumber object,
int a = 10;
NSNumber *myNumber = [NSNumber numberWithInt:a];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:myNumber forKey:#"storedInt"];
NSLog(#"stored number object %#", [defaults objectForKey:#"storedInt"]); // retrieve value from NSUserDefaults
//then change NSNumber object to int value - if required
int retrievedInt = [myNumber intValue];
NSLog(#"int value %u", retrievedInt);

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

What's the safest way to create an 'always logged in' IOS app?

I'm writing code where the user signs up for an account with an e-mail+password. I would like to have login credentials stored in the IOS app, and then used for all remote actions the user makes (create order, update account info, etc.).
Is it safe to store the password in the IOS keychain using PDKeychainBindings and then send the user/pass over HTTPS for every request to the servers?
Is there a better/safer way?
The safest way is not saving the password. Usually, when first connecting, you exchange the username & password for a permanent authorization token.
You then save this token into the keychain and all other server requests are authorized only by the token. You ask the user to enter password again only if the token becomes invalid.
(it's permanent, so it shouldn't expire but it can be invalidated by the server).
There are two ways:
1)You can use KeyChain: http://developer.apple.com/library/ios/#documentation/Security/Conceptual/keychainServConcepts/iPhoneTasks/iPhoneTasks.html
Example:
//Initializing
KeychainItemWrapper *keychainItem = [[KeychainItemWrapper alloc] initWithIdentifier:#"YourAppLogin" accessGroup:nil];
//Saving
[keychainItem setObject:#"password you are saving" forKey:kSecValueData];
[keychainItem setObject:#"username you are saving" forKey:kSecAttrAccount];
//Getting
NSString *password = [keychainItem objectForKey:kSecValueData];
NSString *username = [keychainItem objectForKey:kSecAttrAccount];
//deleting
[keychainItem resetKeychainItem];
2)You can use NSUserDefaults
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
NSString *pword = [prefs setObject:#"yourpassword" ForKey:#"password"];
NSString *username = [prefs setObject:#"username" ForKey:#"username"];
[prefs synchronize];
//getting
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
NSString *pword = [prefs objectForKey:#"password"];
NSString *username = [prefs objectForKey:#"username"];
Method 1 is more secure than method 2. You can make method 2 more secure by encrypting your password and username.
Hope this helps..

How to set initial values for NSUserDefault Keys?

I want to set some initial values for my NSUserDefault keys so that the first run of the app has some reasonable initial settings. I thought I ran across a simple way to do this in the app bundle .plist, but now I can't find it. Any ideas?
You should use the registerDefaults method of NSUserDefaults. Prepare a plist file in your bundle that contains the default preferences and then use that plist to register the defaults.
NSString *defaultPrefsFile = [[NSBundle mainBundle] pathForResource:#"defaultPrefs" ofType:#"plist"];
NSDictionary *defaultPreferences = [NSDictionary dictionaryWithContentsOfFile:defaultPrefsFile];
[[NSUserDefaults standardUserDefaults] registerDefaults:defaultPreferences];
You have to execute this code on every launch of your app. It will add these values to a separate domain in the user defaults hierarchy. Whenever your app's user defaults don't provide a value for a certain key, NSUserDefaults will fall back to this domain and retrieve the value from there.
If you have many default values, let use ola's answer, otherwise this is good for a few params
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
if (![defaults boolForKey:USERDEFAULT_IS_INITIALIZED]) {
[defaults setBool:YES forKey:USERDEFAULT_IS_INITIALIZED];
// Set initial values
...
[defaults synchronize];
}
if ([[[[NSUserDefaults standardUserDefaults] dictionaryRepresentation] allKeys] containsObject:#"initialValuesHaveBeenWritten"])
{
[[NSUserDefaults standardUserDefaults] setValue:obj1 forKey:key1];
[[NSUserDefaults standardUserDefaults] setValue:obj2 forKey:key2];
[[NSUserDefaults standardUserDefaults] setValue:obj1 forKey:#"initialValuesHaveBeenWritten"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
NB: Not tested, done from memory
-(void) loadDef
{
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
_removeAd=[userDefaults boolForKey:SAVE_AD_STATUS];
NSString* strDefSetting=[userDefaults stringForKey:SAVE_STATUS_ADSETTING];
if(strDefSetting==nil
||[strDefSetting isEqualToString:#""]
)
{
strDefSetting=#"0.5";
}
_floatAdmob=strDefSetting.floatValue;//0.5;
}

Resources