Backing up NSUserDefaults and synching iPhone - iphone

Is the application domain in [NSUserDefaults standardUserDefaults] backed up when the user synchs their device? If not, can you suggest a close correct alternative?
Apple makes reference to "Application Preferences" in its documentation, such as regards in-app purchasing. I understand, perhaps incorrectly, that they're making reference to NSUserDefaults here although the terminology doesn't appear to match perfectly.
In-app purchases, which I plan to record in [NSUserDefaults standardUserDefaults], need to be backed up in my project.
Thanking you kindly in advance.

Yes. NSUserDefaults uses a PLIST file as a backing store, which is backed up on each sync. See http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/UserDefaults/Concepts/DefaultsDomains.html for more information.
If you wanted to see for yourself, you could check out ~/Library/Application Support/MobileSync/Backup/. Create an unencrypted backup of a device with just your app on it, and view the files in the PLIST editor.

Related

NSUserDefaults or keychain is better to save username and password in iPhone app

In my iphone app there is some confidential data like username, password and some urls to a webservice.
Which one is better NSUserdefaults or keychain.
Somebody says NSUserdefaults is insecure. Why it is insecure?
and can any one give the pros and cons of each one.
NSUserDefaults is quite easy to use and stores one value per key only. But apparently, it is not a very secure method, as there is no encryption.
But the Keychain is secure, though it is a bit hard to code.
You can refer these link to use keychain access.
http://log.scifihifi.com/post/55837387/simple-iphone-keychain-code
you can also use this library deviced by Simon
https://github.com/goosoftware/GSKeychain
I hope it helps you!!
It may be useful to notice that Keychain data will be persisted even if you app is deleted, but NSUserDefaults data will go away with the app (NSUserDefaults is part of the app sandbox, Keychain is an app-independent service).
Anything stored in NSUserDefaults can be (relatively) easily opened and read, whether on the device or in a (non-encrypted) backup to iCloud or to a sync'd Mac.
Keychain, on the other hand, is meant for stuff like certificates and passwords. I've linked an article titled "How Not To Store Passwords in iOS" which gives a bit more useful detail, as well.
Keychain is way better solution, because it is more secure, but anyway, if you would save this kind of information into the NSUserDefaults, your users wouldn't feel any different. If someone would hack their device, they could get information from Keychain, the same as they would get information from UserDefaults. So this question of security is rhetoric. But anyway, the good programming style is to save this data into the Keychain!
I would recommend you to use Keychains.
Using Keychain, you can store your password in encrypted form. Take a look at Apple's GenericKeychain sample.
NSUserDefaults is a little less secure when compared with Keychain.
In NSUserDefaults data can accessed easily if the specific key is known. This is not the case in Keychain.
You can also convert NSUserDefaults to Keychains. Take a look here.

iOS NSUserDefaults. How do they behave in the context of backgrounding/foregrounding an app?

I am using NSUserDefaults in my app and I am unclear about how NSUserDefaults behave with regard to multi-tasking. Currently I create my NSUserDefaults from a settings.plist file in my project the first time the app is installed and launched. Successive app launches rely solely on NSUserDefaults.
Question: do NSUserDefaults persist even if the user discards the app icon from the multi-tasking dock. Note here I do not mean they have de-installed the app. Just removed it from multi-tasking.
Thanks,
Doug
NSUserDefaults will persist in that case as long as they have been synchronized using the synchronize method.
NSUserDefaults data does persist after the app has been removed from multitasking.
See link
https://stackoverflow.com/a/4771560/716216

NSUserDefaults not being saved in iOS Simulator?

My [NSUserDefaults standardUserDefaults] are not being saved. Everytime I close the app and start it again, it reverts back. I don't have my iOS device handy so I am not sure if this will happen on device, but none of the other apps are doing this in simulator which leads me to believe there's something wrong with my code. I don't know what part of code I should include here, it's just simple add/modify keys in NSUserDefaults and as I said it runs fine during the app, but not after i restart it...
I know I can call synchronize but Apple advices against it and says I should only call it if it's a must... so.
What could be going wrong?
Your process is possibly terminated improperly so that NSUserDefaults do not have a chance to be stored. See also this and mostly this.
The suggestion in the second post I link to is to call synchronize in applicationDidEnterBackground:
Keep also in mind that terminating your app by stopping it in Xcode most often does not save user defaults.
Are you restarting from Xcode / debugger? Try sending the app to background with the Home button first. I think the framework synchronizes automatically then.
I could not understand about the way, you are accessing the NSUserDefault, The static function you used sharedDefaults with NSUserDefault does'nt exist in Apple Documentation
Use As below to access NSUserDefault
[NSUserDefaults standardUserDefaults];
For more read the blog post for using of NSUserDefault.
iPhone Programming Tutorial – Saving/Retrieving Data Using NSUserDefaults

How persistent is [NSUserDefaults standardUserDefaults]?

I'm using [NSUserDefaults standardUserDefaults] for storing application settings.
My questions are:
do those settings are removed on app deletion?
are they kept after an application update (through the
AppStore)?
Because I'm using it to store a password and don't want my users to reset them at each update. Also, I'd like that the only way to reset the password would be to remove the app and re-install it.
Is NSUserDefault the right choice?
Thanks,
Jérémy
Yes, they are removed on app deletion and yes they are kept when an application is updated.
However, you're not advised to store sensitive data in the NSUserDefaults, instead I would look at using the Keychain.
I use NSUserDefaults in my app to allow additional access to my app for my colleagues. They just have to enter the code word in settings and the app is fully opened.
to the point each time I update the app they have to re-enter the code word, so I would say from experience that they are not kept after updates. The values need to be re-entered.

How easy is it to hack a plist file in an app store app?

Don't worry, I'm not trying to hack someone else's app, if that's what you're thinking =).
I want to have 2 versions of my app, a free version and a deluxe version. My plan was to use an in-app purchase to enable the deluxe version by setting a boolean value in the plist file.
My question is: is this secure or is it easily circumvented? And if it is not secure, can someone suggest a simple alternative? I don't want to download additional content, I would rather keep all of the functionality within the app and enable it somehow.
Edit: I don't mean the application plist file, but something like the user defaults file.
You should store this in the keychain, this is what I'll do. The keychain is far more secure than a .plist or the user defaults (which are .plists, too, as far as I know). Have a look at SFHFKeychainUtils, you should be able to use this or just implement a better method exactly for the need to save a simple bool.
It is easy to edit the com.something.plist without jailbreaking. With a free tool* you can browse your device, you can also edit and save these files. If you store your inapp purchase something like this:
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:#"com.example.pack1"];
[[NSUserDefaults standardUserDefaults] synchronize];
then this will be written to the plist:
<key>com.example.pack1</key>
<true/>
If you name your packages like this: pack1, pack2 etc., and somebody edits your plist (copy/pasting the first key), he/she could use the locked feature easily.
A not too hard to implement method would be to save like this:
[[NSUserDefaults standardUserDefaults] setValue:[self sha1ValueForKey:#"com.example.pack1"]
forKey:#"com.example.pack1"];
[[NSUserDefaults standardUserDefaults] synchronize];
where -sha1ValueForKey: is
-(NSString *)sha1ValueForKey:(NSString *)key {
return [self sha1:[NSString stringWithFormat:#"<SALT>%#", key]];
}
You have to change <SALT> to something.
You can find -sha1: here: http://www.makebetterthings.com/iphone/how-to-get-md5-and-sha1-in-objective-c-ios-sdk/
After this you can verify if the key matches the hashed value.
If somebody wants to hack your plist he/she has to know your hashing mechanism and salt.
This is not the safest way to protect your application but it is easy to implement.
*iExplorer
EDIT:
The suggested method only protects - somewhat - your IAP if the user doesn't have access to the hashed value. If someone gets it from somewhere, it is easy to copy that data to the plist. If the SALT is device dependent copying is useless.
I would recommend reading up on verifying in-app purchases. It sounds to me like you are trying to roll your own in-app purchase verification system which may be wrought with issues you might not have thought of yet. You have to be careful with your user's purchases that they will behave the same in your application as they will in any other, lest ye lose their trust (and future sales!)
Instead of worrying about the Info.plist file, why not just set a preference? Somewhere in your code, this would give you your boolean value:
[[NSUserDefaults standardUserDefaults] boolForKey:#"someKey"];
If the value doesn't exist, the result will be nil. This code sets the value:
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:#"someKey"];
Plus, these values will be backed up in iTunes, so if the user moves their backup to a new iPhone or simply restores from backup, the values will be restored.
I don't have an answer, but it seems that editing your plist file dynamically is not possible, if I trust this subject :
You can not edit you're info.plist
file dynamically. When you submit your
app to The App Store, your app bundle,
which includes info.plist, can't
change because the signature created
when you compile you app is based on
the bundle.
Any pirate has a jail-broken iPhone
Any jail-broken device offers full file system access via tools like PhoneDisk, etc
Any file system access allows people to change the values in your applications .plist file
Game over.
Now, its not trivial to wrapper that up for the script kiddies but then again its not that hard either.
Storing state in defaults is no more nor less safe from privacy than having two versions of your app. Pirates will either pirate the deluxe version, or they'll pirate the unified version with the flag set.