Data persistance in cocoa for small amount of data - objective-c

I'm busy writing my first cocoa application and I have to store 2 NSStrings somewhere on the hard disc (an username and password). What would be the best way to do this? Just write to a file? And if so, where would be the best place for me to store this file?
I just don't want to use some overkill technique for just 2 simple Strings.. Thanks!

The easiest is using UserDefaults. It's a place usually used to store application's settings and preferences.
To store a string
NSString *user = #"Peter";
[[NSUserDefaults standardUserDefaults] setObject:valueToSave forKey:#"userName"];
to get it back later
NSString *user = [[NSUserDefaults standardUserDefaults] stringForKey:#"userName"];
If you're saving a password, you might consider encrypting it, or instead of storing the password, store the hash for the password.

First encrypt Username and Password strings with MD5, SHA-1 or other algorithm.
After use:
NSUserDefaults* prefs = [NSUserDefaults standardUserDefaults];
[prefs setObject:encryptedUsername forKey:#"userName"];
[prefs setObject:encryptedPassword forKey:#"password"];
[prefs synchronize];
// To retrieve info
encryptedUsername = [prefs objectForKey:#"userName"];
encryptedPassword = [prefs objectForKey:#"password"];
After encrypt the user input data and compare the encrypted strings.

Related

Saving NSUserDefaults Issue?

i have been working on a app, and needed to store a string. I used this code to set the default:
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setValue:CertificateKey.stringValue forKey:#"SavedKey"];
[[NSUserDefaults standardUserDefaults] synchronize];
NSLog(#"%#",[defaults objectForKey:#"SavedKey"]);
I loged it, so i know it saved...well, it showed me the value.
When i open my application, I use this to retrieve the default:
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[CertificateKey setStringValue:[defaults objectForKey:#"SavedKey"]];
[CertificateKey setTitleWithMnemonic:[defaults objectForKey:#"SavedKey"]];
[[NSUserDefaults standardUserDefaults] synchronize];
Why will it not get the default value? Did i not completely save it?
Don't quit the application by pressing the stop button in xcode. Instead, quit it by right clicking on the application icon and selecting "Quit".
Edit
Maybe the first time that you execute the application, you want to save some defaults but you don't want to set them the second+ time that the application runs.
For this purpose in some class initialize method register the defaults, like this:
+ (void) initialize
{
NSUserDefaults* defaults= [NSUserDefaults standardUserDefaults];
[defaults registerDefaults: #{} ];
// This case it's an empty dictionary, but you can put whatever you want inside it.
// just convert it to data if it's not an object storable to a plist file.
}
Also, you're using setValue:forKey: , that method is inherited from NSObject. Use setObject:forKey: .
And use finalize if you want to save the defaults at the end:
- (void) finalize
{
// Save the defaults here
}
You might have a problem because you are creating an instance of NSUserDefaults. From what I understand you are supposed to access it like so: [[NSUserDefaults standardUserDefaults] setValue:#"Pikachu" forKey:#"Best Pokemon Ever"]; [[NSUserDefaults standardDefaults] objectForKey:#"Best Pokemon Ever"]; Rather than actually creating an instance of it.

Switching between NSUserDefaults

Maybe somebody will know, how to "tag" NSuserdefaults.
I have like 10 user defaults:
name
pin
etc...
I want to make another object, which would have the same defaults as the other ones (same variables but different values). Like a version, if object == 1 then load one userdefaults and if object == 0 another ones. But how to make it done?
Tried to make something like this
[NSUserDefaults setVersion:object.intValue];
But i guess this isn't the way to do it. So maybe anyone could help how to make it done?
To be more specific a simple example would help like how to do this:
Object (1 or 0)
[[NSuserDefaults standartUserDefaults] setObject: #"something"
forKey: #"Name"];
[[NSUserDefaults standartUserDefaults] synchronize];
NSString *name = [[NSUserDefaults standartUserDefaults] stringForKey:"#name"];
How to set and get this Name depending on Object value?
You could use persistent domains.
NSMutableDictionary *defaults = [[[NSUserDefaults standardUserDefaults] persistantDomainForName:#"aString"] mutableCopy];
// make changes to the dictionary here
[[NSUserDefaults standardUserDefaults] removePersistentDomainForName:#"aString"];
[[NSUserDefaults standardUserDefaults] setPersistantDomain:defaults forName:#"aString"];
Note that you'll need to be accessing all the defaults via the dictionary if you do this.

Problems in loading from NSUserDefaults

I have a very strange problem while my app loads from NSUserDefaults.
This is the code in my appDelegate:
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSString *user = [[NSString alloc]initWithString:[defaults objectForKey:#"_settingsUsername"]];
NSString *password = [[NSString alloc]initWithString:[defaults objectForKey:#"_settingsPassword"]];
NSString *instance = [[NSString alloc]initWithString:[defaults objectForKey:#"_settingsInstance"]];
The error is this: [NSPlaceholderString initWithString:]: nil argument'
It's very strange because i put in Settings.bundle -> Root.plist the default values for all the fields above.
Oddly that's how it's supposed to work -- this confused me too initially.
I guess the thing to remember is that you can use NSUserDefaults without the Settings.bundle, so it can't be the only way to set default values.
Apple provide sample code, AppPrefs, that shows how to copy the default value from the settings to NSUserDefaults.
Why don't you just use that?
NSUserDefaults *defaults = [NSUserDefaults standarduserDefaults];
NSString *user = [defaults objectForKey:#"_settingsUsername"];
NSString *password = [defaults objectForKey:#"_settingsPassword"];
NSString *instance = [defaults objectForKey:#"_settingsInstance"];
And make sure that there are objects for these keys.
hope it helps
I think the problem is that if the user hasn't gone into the settings for your app yet then all values returned from NSUserDefaults for those keys are nil. You need to handle that case and act accordingly - probably by going into the Settings.bundle and picking out the default value that you have put in there. I would just write a method that gets the value for a key and if NSUserDefaults returns nil it handles all the querying of the settings bundle for you.

Best Way To Keep A User-Modified List Of Application Names

I'm looking for the best way to deal with a modifiable list of application names in an app's "Preferences" to be used as a filter.
I'd like to be able to have a few defaults in this on first run, and for the user to be able to modify this array.
So what's the best way to create and store a default array of Application Names (or anything, really) that can be modified and saved as a preference by a user?
NSArray saved somewhere? A really long entry in my defaults.plist?
If you just want to store an array of strings, the quickest and simplest way to do that is using NSUserdefaults. Very very easy to use.
-(void)saveToUserDefaults:(NSString*)myString
{
NSUserDefaults *standardUserDefaults = [NSUserDefaults standardUserDefaults];
if (standardUserDefaults) {
[standardUserDefaults setObject:myArray forKey:#"StoredArray"];
[standardUserDefaults synchronize];
}
}
-(void)retrieveFromUserDefaults
{
NSUserDefaults *standardUserDefaults = [NSUserDefaults standardUserDefaults];
NSArray *myArray = nil;
if (standardUserDefaults)
val = [standardUserDefaults objectForKey:#"StoredArray"];
//do something with your array
}

Save Username & Pass Objective C iPhone

i have a textfield,
Number and Password
i have no clue how to save these settings and then read them as the app starts to check if they have been set or not.
Thanks
Mason
Sensitive information should be stored in the keychain, a cryptographically secure location on the device. If you save the username and/or password in NSUserDefaults, you're saving them as plaintext, which is inherently insecure.
There're are plenty of examples on the internet of how to use the keychain on the iPhone, include simple wrappers to use in your code. For example, here's some pretty good code on Github that makes it quite easy:
http://github.com/ldandersen/scifihifi-iphone/tree/master/security
To Save:
[[NSUserDefaults standardUserDefaults] setValue:_email forKey:#"email"];
[[NSUserDefaults standardUserDefaults] setValue:_password forKey:#"password"];
[[NSUserDefaults standardUserDefaults] synchronize];
To Read:
_email = [[NSUserDefaults standardUserDefaults] stringForKey:#"email"];
_password = [[NSUserDefaults standardUserDefaults] stringForKey:#"password"];
In your case:
[[NSUserDefaults standardUserDefaults] setValue:Number.text forKey:#"Number"];
And:
NSString * number = [[NSUserDefaults standardUserDefaults] stringForKey:#"Number"];
The "Key" is usually hard-coded and works like a "variable name" for things in storage (typical name/value pairs like a dictionary).
To check if the value has been set or not; after you read it:
if (number) ...