I have a simple application, based of the "Utility Application" template. It retrieves a password-protected XML file (via NSXMLParser).
I want to allow the user to set a username and password in the "FlipsideView", how would I go about this?
I have the basics in place, the two UITextField boxes, the value of which gets set to a fixed value when the view loads (using the viewWillAppear method), and NSLog'd when the view is closed (the NSLog is just for testing, obviously, in the viewWillDisappear method)
How do I store the data? I've had a look at the Developer documentation, and it seems like I should be using NSUserDefaults..?
I agree with Ben. This is exactly what the Keychain is for.
I would not, under any circumstances simply store passwords in the defaults as dbr suggests. This is highly insecure. You're essentially storing your passwords in the open.
In addition to Apple's sample code, I also recommend Buzz Anderson's Keychain code:
iPhone Keychain Code
This is exactly what Apple developed the Keychain for. Using Keychain, you can store your password in encrypted form. Take a look at Apple's GenericKeychain sample.
Aha, NSUserDefaults seems to work, and is simple to use, but isn't secure in the slightest:
password is the IBOutlet for the UITextField.
- (void)viewWillAppear:(BOOL)animated
{
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
NSString *pword = [prefs objectForKey:#"password"];
password.text = uname;
}
- (void)viewWillDisappear:(BOOL)animated{
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
[prefs setObject:password.text forKey:#"password"];
}
The password is stored in plain-text in a plist, so it would be quite easy for someone else to access.. but this is useful for storing non-sensitive settings.
I ended up using this to store the username field, and stored the password using the SFHFKeychainUtils keychain code from August's answer.
Related
I am developing one application. In my application I want to develop log in page using a plist.
My requirement is when user enters username and password they go to next view.
How do I create a log in page?
I am new to the programming. Please send me any tutorial or sample code.
Thanks in advance
I don't know why you are try to use plist for that. You can (and should) use NSUserDefaults (this is also plist but easy to manage).
Try to save data:
[[NSUserDefaults standardUserDefaults] setObject:#"myName" forKey:#"userName"];
and later get:
[[NSUserDefaults standardUserDefaults] stringForKey:#"userName"];
Of course i probably don't have to tell you that storing password in plain text is a very bad idea in general.
I'm wondering how I can add some kind of setup to my App so when the user launches the App it asks a couple of questions and based on those questions it redirects to a specific view and the next time the app launches it will continue there again.
Is there any way to achieve this, because I'm unsure where I should start searching for.
I did something similar in my last project. There the user had the option to use the application connected with facebook or not. For storing the decision of the user I used a key/value pair in the NSUserDefaults. It's very easy to read/write and its persistently stored in the apps filesystem.
I first checked the NSUserDefaults if the key/value pair already exists.
If not, I did a redirection to a ViewController containing the two buttons (With FB/No FB)
Then depending on the selection of the user I setted the NSUserDefault key.
If yes, I did read the NSUserDefaults and get the value of the key.
Depending on the loaded value I redirected him to the FB ViewController or the the normal one.
Here a short example of reading the NSUserDefaults:
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
NSString *myString = [prefs stringForKey:#"keyToLookupString"];
Here a short example of writing the NSUserDefaults:
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
[prefs setObject:#"TextToSave" forKey:#"keyToLookupString"];
I guess the only difference to your application is that you have several values to store but for that you can still use the NSUserDefaults. You could also use the CoreData to store the information but I think in that case using the NSUserDefaults is the way to go.
as I get closer to releasing my app, I'm trying to make sure that I'm using stable code to check if the app has been launched before (in order to perform some first time setup). Is this (obviously a no frills method that doesn't take into account app version and updates) pretty much a rock solid way to determine if the app has been launched?
In my app delegate didFinishLaunchingWithOptions method, I perform the following each time:
NSUserDefaults *defaults =[NSUserDefaults standardUserDefaults];
if(![defaults objectForKey:#"not_first_launch"])
{
NSLog(#"This is the first time the app has been launched.\nPerforming first-time setup procedures...");
[self runFirstTimeSetup];
}
My second question is basically, can I assume that when I release an app update, that the user's documents directory for my specific app's sandbox will be left unerased? Does an app update simply add to the directory, not wipe it clean and re-install? I need the user's files to stick around even when I update the app (pretty obvious) but I don't want to make the wrong assumption and have users lose data every time I release an update.
Thanks!
Yes, that's a good use of NSUserDefaults.
User data is preserved through updates.
Just make sure you keep the data that comes with your app and the data generated during runs in separate bins. So that if you have to change the former (via an app update), the latter remains untouched. For example, don't put both of them in the same SQLite table.
I know you already accepted an answer, but I just wanted to touch on the subject. The way I check if the app is being launched for the first time is like this:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
...normal code...
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
if (![defaults objectForKey:#"kFirstUse"]) {
[defaults setObject:[NSDate date] forKey:#"kFirstUse"];
[defaults synchronize];
}
}
The reason why I wanted to post is because while I check if this is the user's first launch, I also save the date of their first launch. For no extra code, I figured why not save this first launch date. I don't use that info at all in my app, but I was thinking maybe in the future I might. In the future, I was thinking about adding in App Purchase, and I would give the stuff away for free to my initial users; so this allows me to be prepared for the future and accomplish my goal at the same time.
And just for completeness, NSUserDefaults do persist between app updates, just make sure not to change the key to any object, otherwise that object won't be found.
Another good thing to add is that line [defaults synchronize]; - that literally makes the app save that data. The app periodically automatically saves the data, but I like to be safe and know that my stuff is saved.
let me know if you have any other questions
I am new in iphone programming. I am making an application in which I want to enter the name, location etc using iphone application and store it into database, so that I can retrieve any name any time or can store any user entry any time.
How can I implement this? Please give me some solution.
Thanks alot.
You should use CoreData, a sqlite3 wrapper.
iOS 4 CoreData tutorial
If you want to store only name and location use NSUserDefaults class instance as below.
NSUserDefaults *standardUserDefaults = [NSUserDefaults standardUserDefaults];
use google for NSUserDefaults examples.
As told by #Antwan van Houdt, You can go for CoreData or sqlite3.
So, NSUserDefaults is quite easy to use. But apparently, it is not too secure - there is no encryption. And of course the client wants the app prefs to be secure because it contains sensitive data.
But the Keychain is secure, though hard to code (apparently). So is there a way to easily convert NSUserDefaults code to Keychain code? In other words, I want to store app prefs within the Keychain. Or am I barking up the wrong tree?
Both of the below solutions are wrappers around KeyChain API. By using them in a NSUserDefaults category, you can have clean way to access and store passwords.
For Mac OS X
You can try the EMKeyChain library that wraps the keychain in a friendly manner. If you need to store passwords, it is as simple as NSUserDefaults.
For iPhone
There is a simple wrapper: Simple iPhone Keychain Code.
For iOS (and possibly OS X) you can use my GSKeychain library. Sample usage:
// Store a secret
[[GSKeychain systemKeychain] setSecret:#"t0ps3kr1t" forKey:#"myAccessToken"];
// Fetch a secret
NSString * secret = [[GSKeychain systemKeychain] secretForKey:#"myAccessToken"];
// Delete a secret
NSString * secret = [[GSKeychain systemKeychain] removeSecretForKey:#"myAccessToken"];
Hope this helps!
It's extremely simple to do that using the PDKeychainBindings library.
Here is an article i wrote about it recently.
Sample code
Instead of this
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[[Model sharedModel] currentUser] setAuthToken:[defaults objectForKey:#"authToken"]];
Use this
PDKeychainBindings *bindings = [PDKeychainBindings sharedKeychainBindings];
[[[Model sharedModel] currentUser] setAuthToken:[bindings objectForKey:#"authToken"]];