what is the best way for saving username and High Score - iphone

In my app I need to save a double value (high score) and String (player name) what should i use to get this.
any idea will be great.
Thank you

If this is all you're saving then NSUserDefaults should be fine
// To store
[[NSUserDefaults standardUserDefaults] setObject:name forKey:#"name"];
[[NSUserDefaults standardUserDefaults] setDouble:score forKey:#"score"];
// To read back in
NSString *name = [[NSUserDefaults standardUserDefualts] objectForKey:#"name"];
double score = [[NSUserDefaults standardUserDefaults] doubleForKey:#"score"];
// Don't forget that your name is autoreleased - if you want to keep it, set it to a retained
// property or retain it yourself :)

As deanWombourne said, you can use NSUserDefaults to store these data but it isn't very secure. If you don't want to store this data "in the air", you can take a look to SFHFKeychainUtils by Buzz Andersen to store them in the iPhone Keychain.
First of all, copy SFHFKeychainUtils files to your project. Click on the SFHFKeychainUtils.m and click on Get Info. Go to Target tab and check if the box near your target is checked. If not, check it. Control-click on your Framework folder and select Add Existing Framework. Find Security.framework and add it to your project. Check also that this framework is added to your target by doing the same procedure done for SFHFKeychainUtils.m. Now open you implementation file on where you want to use this code and add on the top #import "SFHFKeychainUtils.h".
This is a little example on how to use this code:
// to store your data
NSError *error = nil;
[SFHFKeychainUtils storeUsername:kName andPassword:name forServiceName:kStoredName updateExisting:YES error:&error];
[SFHFKeychainUtils storeUsername:kScore andPassword:score forServiceName:kStoredScore updateExisting:YES error:&error];
// to get them back
NSString *name = [SFHFKeychainUtils getPasswordForUsername:kName andServiceName:kScoredName error:&error];
double score = [SFHFKeychainUtils getPasswordForUsername:kScore andServiceName:kScoredScore error:&error];
// kName, kScore, kStoredName, kStoredScore are defined key but you can use also strings with #"your string here".
// It is important that when you store and get back a value, username and serviceName must be the same.

Related

NSUserdefaults for multiuser

In my application, I am using a login form to enter into the application, also using NSUserDefaults to store user preferences, for example:
[storeData setObject:self.loginField.text forKey:#"USEREMAIL"];
[storeData setObject:self.PasswordField.text forKey:#"PASSWORD"];
Like I stored, if a new user logs in the NSUserDefaults stored value will be changed. But I want both preferences (ex:new userid and old userid as well as password). So please explain how to store multiple values for same key?
One way to solve this would be to store a NSDictionary with UserIDs as keys and the passwords as values.
Another option is to use Keychain as it specifically designed for this kind of thing and is also more secure.
Create a Global NSMutableArray and add above details in NSDictionary Objects and Store all Objects in array.This way you will have all user objects.You can get it whenever you want.
first of all create global array with AppDelegate class, for example..
userDefaults = [NSUserDefaults standardUserDefaults];
NSData *dataRepresentingtblArrayForSearch = [userDefaults objectForKey:#"arrScheduleDates"];
if (dataRepresentingtblArrayForSearch != nil) {
NSArray *oldSavedArray = [NSKeyedUnarchiver unarchiveObjectWithData:dataRepresentingtblArrayForSearch];
if (oldSavedArray != nil)
arrScheduleDates = [[NSMutableArray alloc] initWithArray:oldSavedArray];
else
arrScheduleDates = [[NSMutableArray alloc] init];
} else {
arrScheduleDates = [[NSMutableArray alloc] init];
}
[arrScheduleDates retain];
after that when you want to store the new record then get all record from arrScheduleDates array and after that add the new record and after that store like whole array like above..
i hope you understand and its helpful for you...
:)
The absolute easiest way to meet your requirements is to use the user's email address (assuming they're all unique) as the storage key for your dictionary, and the password as the value.
If you need to store more than the password, then the value of the key would be another dictionary with keys and values for the user.
An example of the simple case would look similar to :
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
NSDictionary *storedUsers = [userDefaults objectForKey:#"userData"];
if (nil == storedUsers) storedUsers = [NSDictionary dictionary];
NSMutableDictionary *mutableStoredUsers = [NSMutableDictionary dictionaryWithDictionary:storedUsers];
NSString *userPassword = [self.PasswordField.text copy]; //add autorelease if you aren't using ARC
NSString *userEmail = [self.loginField.text copy]; //add autorelease if you aren't using ARC
if (nil != userEmail)
{
[mutableStoredUsers setObject:userPassword forKey:userEmail];
}
[userDefaults setObject:[NSDictionary dictionaryWithDictionary:mutableStoredUsers] forKey:#"userData"];
[userDefaults synchronize];
first download and import files of given link
https://github.com/ldandersen/scifihifi-iphone/tree/master/security
then where u want to store user preferences write this code
[SFHFKeychainUtils storeUsername:loginField.text andPassword:PasswordField.text forServiceName:#"dhaya" updateExisting:YES error:&error];
where u want password write this code
NSString *password = [SFHFKeychainUtils getPasswordForUsername:loginField.text andServiceName:#"dhaya" error:&error];
NSLog(#"passwordpassword %#",password);
this will working great....

Settings Bundle values not being linked correctly on iPhone

I have an issue I've been struggling with for the last few days. I have a settings bundle, root.plist, which holds some user preferences. In it are three multivalue menu items. One returns a boolean, the other two return numbers.
When I call [[NSUserDefaults standardUserDefaults] dictionaryRepresentation] and examine it in the console, only the first item in the property list shows up with its value. The other two are conspicuously absent. As a result, when I try to retrieve those values, I get zero.
What's weirder is that the settings bundle looks correct in the Settings app on the iPhone. The only thing not working is that the values are not getting passed. As far as my app is concerned, the other two multivalue menu items don't even exist.
Any suggestions are greatly appreciated.
I've used this block of code, multiple times, in applicationDidFinishLaunchingWithOptions to initialize my user defaults.
if (![[NSUserDefaults standardUserDefaults] objectForKey:#"somePropertyYouExpect"]) {
NSString *mainBundlePath = [[NSBundle mainBundle] bundlePath];
NSString *settingsPropertyListPath = [mainBundlePath
stringByAppendingPathComponent:#"Settings.bundle/Root.plist"];
NSDictionary *settingsPropertyList = [NSDictionary
dictionaryWithContentsOfFile:settingsPropertyListPath];
NSMutableArray *preferenceArray = [settingsPropertyList objectForKey:#"PreferenceSpecifiers"];
NSMutableDictionary *registerableDictionary = [NSMutableDictionary dictionary];
for (int i = 0; i < [preferenceArray count]; i++) {
NSString *key = [[preferenceArray objectAtIndex:i] objectForKey:#"Key"];
if (key) {
id value = [[preferenceArray objectAtIndex:i] objectForKey:#"DefaultValue"];
[registerableDictionary setObject:value forKey:key];
}
}
[[NSUserDefaults standardUserDefaults] registerDefaults:registerableDictionary];
[[NSUserDefaults standardUserDefaults] synchronize];
}
Make sure you are using - (void)registerDefaults:(NSDictionary *)dictionary on NSUserDefaults. Otherwise your defaults will not get pulled from the Bundle.
You have to do this early in your application, before you try to retrieve any of the default values.
http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSUserDefaults_Class/Reference/Reference.html

How to make a dump of the current NSUserDefaults standardUserDefaults state to disk and read back in?

I want to have some way of backing up the user defaults to a property list or XML, or some other appropriate file format that can be transfered over the net. How could I get a backup of these so that I can send them to a webserver and retrieve them back to the device and read them in to the user defaults database?
You can get a JSON string of the user defaults like this :
// You will need this at the top of your file
#import "CJSONSerializer.h"
// Get a dictionary of the user defaults
NSDictionary *dict = [[NSUserDefaults standardUserDefaults] dictionaryRepresentation];
// Convert them to JSON
NSString *json = [[CJSONSerializer serializer] serializeObject:dictionary];
and to read them back into the device you can just do the opposite :
// You will need this at the top of your file
#import "CJSONDeserializer.h"
// Get the data from the server and re-create the dictionary from it
NSData *jsonData = <YOUR DATA FROM THE SERVER>;
NSDictionary *dict = [[CJSONDeserializer deserializer] deserializeAsDictionary:jsonData error:nil];
// Put each key into NSUserDefaults
for (id key in [dict allKeys]) {
id object = [dict objectforKey:key];
[NSUserDefaults standardUserDefaults] setObject:object forKey:key];
}
[[NSUserDefaults standardUserDefaults] synchronize];
Have a look at the TouchJSON project page for more details and the download link.
Hope that helps.
NB There's no error checking in the above code - you might run into problems if your JSON contains int / float / etc because setObject:forKey: will fail.
I'd suggest either XML or JSON. Both have pretty good frameworks that ease working with them (TouchXML and TouchJSON).

iPhone code to create new NSUserDefaults objects?

I have NSUserDefaults storing a number of string variables for things like name, date of birth, address, etc. What I would like to know is how to write a code that will create a new object for each new user. For example, I have a spinning wheel that shows up immediately after the first time the user runs the app. What I want, is for that wheel to have one single option - "New User". Once that New User fills out a bunch of text fields that I am using NSUserDefaults to save, I want that user to be saved on that spinning wheel so that the next time they open up the app they have the option of returning to all of the variables that they previously put in, or creating a new user so they can input all new variables.
I know how to do everything except write the code to create new users automatically. Potentially, the program should allow for a limitless number of these user objects and then just use something arbitrary like their last name to input into the spinning wheel. I would assume that the code would need to be put somewhere in the following code used to save the NSUserDefaults:
NSUserDefaults *userData = [NSUserDefaults standardUserDefaults];
[userData setObject:txtName.text forKey:#"name"];
---EDIT FOR CLARIFICATION ----
I am able to put multiple strings into this 'userData' object already by simply adding more lines like the 2nd line from above. What I want to know is how to add 'user2Data', 'user3Data', 'user4Data', 'usernData'..........to make a potentially limitless amount of user objects to store these variables?
You can add NSArray objects to NSUserDefaults.
NSUserDefaults *userData = [NSUserDefaults standardUserDefaults];
NSMutableArray *users = [NSMutableArray mutableArrayWithArray:[userData objectForKey:#"users"];
[users addObject:txtName.text];
[userData setObject:[NSArray arrayWithArray:users] forKey:#"name"];
[userData setObject:txtName.text forKey:#"name"];
If you need more than a single string for user data, you can look at using an NSDictionary object.
All that said, if you're going to be storing a lot of data, you should look at maybe saving .plist files in your app's Library directory.
You could modify the following to meet your needs, to be put into your app delegate:
+ (void) initialize
{
if ([self class] == [MyAppDelegate class]) {
// initialize user defaults dictionary
BOOL isFirstTimeRun = YES;
...
NSMutableDictionary *resourceDict = [NSMutableDictionary dictionary];
[resourceDict setObject:[NSNumber numberWithBool:isFirstTimeRun] forKey:kIsFirstTimeRunKey];
...
[[NSUserDefaults standardUserDefaults] registerDefaults:resourceDict];
}
}
...
- (void) applicationDidFinishLaunching:(UIApplication *)application
{
if ([[[NSUserDefaults standardUserDefaults] objectForKey:kIsFirstTimeRunKey] boolValue]) {
// you could do first-time-run stuff here, such as initializing
// other data model elements...
}
...
}
...
- (void) applicationWillTerminate:(UIApplication *)application
{
// if we're quitting the app, it must have been run at least once
if ([[[NSUserDefaults standardUserDefaults] objectForKey:kIsFirstTimeRunKey] boolValue])
[[NSUserDefaults standardUserDefaults] setObject:[NSNumber numberWithBool:NO] forKey:kIsFirstTimeRunKey];
...
}
What you probably want to do is create a property list for each user, and save the list of users in your NSUserDefaults. Once a user has been selected, you can then load the contents of the property list for that specific user and load/store all data in that particular property list. The basics of this approach is to use an NSDictionary* wherever you need to read from the property list and an NSMutableDictionary* whenever you need to both read and write to it. When you first construct the property list, you simply instantiate an NSMutableDictionary. When you want to save it or load it, you can use the NSPropertyListSerialization class in order to save or load the dictionary from/to a property list.

iPhone One Time Events Programming

How can I make my application display something only when they first launch the application for the first time. Example: They open up my app, an alert comes up, saying something like, "Do you want to play the tutorial?" Then, if they close the app, then re-open it, it won't show up again.
Thanks
I'd recommend using NSUserDefaults:
- (void)openOneTime
{
NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
static const NSString* kKey = #"One Time Key";
NSObject* keyValue = [defaults objectForKey:kKey];
if (keyValue == nil)
{
[self doMyOneTimeThing]; // pop a dialog, etc...
}
// Adds an object for our key which will get found the next time around,
// bypassing the above code block. The type and value of the object is
// not important; what matters more is that an object exists for that
// key at all.
[defaults setBool:YES forKey:kKey];
}
More tips on storing data persistently:
Method 1: Use the global user preferences system. You can do this, but it might be considered slightly hacky because it is designed to store user preferences, and I think this is a gray area, since the user doesn't have explicit control here. In any case, check out the docs for NSUserDefaults to find out how to do that.
Method 2: Write to a file whose existence indicates whether or not the tutorial has been viewed. You can easily create a file with an NSData object by calling its writeToFile:atomically: method. Later, you can use the NSFileManager class to check if that file exists or not.
Sample code:
- (NSString*) filename {
NSArray* paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
NSUserDomainMask, YES);
NSString* documentsDirectory = [paths objectAtIndex:0];
return [documentsDirectory stringByAppendingPathComponent:#"notFirstTime"];
}
- (void) setNotFirstTime {
NSData* data = [[[NSData alloc] init] autorelease];
[data writeToFile:[self filename] atomically:YES];
}
- (BOOL) isNotFirstTime {
return [[NSFileManager defaultManager] fileExistsAtPath:[self filename]];
}
You could store in your property store a boolean value saying whether it's the first time or not, then check that on application start.