Saving app settings - iOS - ios

I have an iOS app which loads certain features depending on the settings that the user sets. Currently I am using NSUseDefaults to save and retrieve these settings and it works fine. But from what I understand anyone can view and edit them with a simple XML editor. You don't even need to jailbreak an iOS device to gain access to them. So they arn't very secure.
I was wandering if anyone could give me some advice on how I can go about saving app settings (these are NONE secure settings, no passwords, just simple things like ints and strings).
Here are a few ideas I had:
IDEA 1 Add a JSON file to the app NSBundle and then edit/save that JSON file every time you want to load/change the app settings.
IDEA 2 Use Keychain - it can store strings right? And it can't be accessed or edited by anyone. (hopefully even the NSA... lol). I could just store an array of strings in keychain for my app settings.
IDEA 3 Store the settings on a server and get the app to pull them down for the user every time they use the app.
IDEA 4 If NSUserDefaults supports this, then maybe locking the NSUserDefaults so that the end user can only view them but not edit them. Only the app will be able to edit them.
The main point is that I am worried that if I use NSUSerDefaults, the user may see them and edit them and then the app will not function properly. While I am not storing any kind of secure data, it would be nice if I can prevent the user from editing the app settings.
Are any of these approaches any good?
Thanks for your time, Dan.

All of them are good ideas, but just one issue with the first one:
You can not write or change files in the main bundle.
As long a the sure did not jailbreak their device the NSUserDefault can not easily be changed.
The keychain should only be used for password, token, etc..
In you case the NSUserDefault will do just fine, or just save the some file the documents directory of your is also an option. You can even create you now settings class that conforms the to NSCoding protocol and you can save it.

Related

Best way in iOS and Swift to store a server-supplied credential between app launches

I need to store a persistent remember token (a string) between app launches and device restarts. The token will be provided by a server once my user logs into the app and its back end service (which is already built). Specifically, I need to set up a persistent data placeholder for the remember token but I don't ever want the code to actually set the value of that placeholder.
On the one hand, it seemed like NSUserDefaults (now called UserDefaults) was a simple way to do this, but after reading the documentation, it doesn't seem like that was the intention of the feature. All the documentation I've see shows setting it up by assigning a value to a key. I definitely don't want to ever have the app assign a value to that key.
What's the simplest way to do this?
The simplest way to achieve that while also taking security into consideration is to use the Keychain. Data stored in the Keychain is encrypted using the key one provides for example when setting the Touch ID support.
You should never, ever, ever, use UserDefaults for such a task. The reason is UserDefaults are backed by the simple, unencrypted .plist file that is a part of your bundle, and can be more or less easily viewed by anyone that can get access to your ipa (e.g. anyone with jailbroken device).
The KeychainAccess API is written in Objective-C, but there are numerous wrappers that encapsulate this using Swift. You can use this on https://github.com/kishikawakatsumi/KeychainAccess

Why is it obvious to not store password in NSUserDefaults?

I've been googling around on how to store a password, and most of the people say that the only acceptable option is Keychain. I implemented that kind of approach, due to rush. But now I am curious what is that obvious thing to not store passwords in NSUserDefaults and is it ok to store password in CoreData?
So far I understood that NSUserDefaults are stored as a plain text in plist file. But how may one access this file? I've read that it is possible to do with the help of a lightning cable and an itunes, but didn't find how to do that.
Thanks in advance!
Data you store using NSUSerDefault are getting saved in simple plist -in binary format without any encryption. there are many tricks to read these data or modify these data.
Jailbreak users can use iFile to view or modify plist files. Non-Jailbreak users can use other software like iExplore - iFunBox to do this. This software allows users to explore the iOS filesystem without having phone jailbroken
Long story short -- anyone can see or modify data in NSUserDefault. So if you don't want to share your detail publicly, you should never store them in NSUserDefault.
The problem in here is Jailbroken device, while the device is Jailbroken, it will allow other app/tweak to intercept with the sandbox files inside the app, thus can search/read the .plist file in there, atleast thats what i know of

iOS: Storing user registration details

I an building my first iOS application and I need to store the user registration details of the user using the application. The details include his mobile number and a unique id( uuid ) which I use to contact with the backend. It would be great if I could get a suggestion on where to store this user details.
Should I be storing this in the NSUserDefaults or should I be using Keychains to store this data or even may be a using a user model in the database ( I would need a database in any case to store a few other details ). Just to add on, I also would like to perform a few validations like if the mobile number is of proper format and so on before I could actually save it. Also can any one please suggest on the security aspects of different storage mechanisms possible here?
Any help on this would be much appreciated.
The most secure way would be to use keychain services as the data is encrypted but in your scenario it seems a bit over kill. I would recommend either just using NSUserDefaults or an sqlite database I wouldn't really recommend storing in a plist as this can be accessed really easily.
But this all depends on the data you are getting, if it was just uuid and mobile number then NSUserDefaults would do probably, whereas if you were getting usernames and passwords and other personal data I would looking a mix of keychain and sqlite database.
Also you could use coredata file to store user data but seems a bit over kill as well for for such little data.
Just a little note you are actually not allowed to get the iPhones mobile phone number programmatically, getting this would use Private APIs that Apple would reject your app for using.
2.5 Apps that use non-public APIs will be rejected
So you would have to ask he user for this.
Database selection is totally depend on the architecture and security, if you just need to store the few information like login details and some field then Keychain for login details and plist for data is best option, but if your application also working with services and fetching and saving lots of data and continuously updating it then a serious database structure required. In that scenario core data and sqlite both are good option depends on your preference
Following ways you can save details.
In NSUserDefaults
In coredata file.
In sqlite database
Plist file.(Not recommended)
You can save data at server site using webservice.
Any one of these you can use according to your requirement and data.
Cheers :)
If you store information on the UserDefaults, a jailbroken device can see the information you have stored, it is a plist after all. If you are going to keep sensitive data on your device, user defaults itself is not a good option. Possible alternatives:
Use keychain: Keychain is a tool to keep usernames & passwords securely on a device; so you may need to find a way to convert all the info you have mentioned ( a dict, I presume? ) into NSData and put into/get from the keychain but it's been explained on other threads. Additionally, keep in mind that when the app is deleted, keychain data will persist on the device.
UserDefaults & encrpytion: If you can encrypt the data yourself, than using UserDefaults might be a better option. Its more straightforward than keychain and it will be deleted if you delete the app from the device (which may be the thing you want, or not. It depends)

How to store user-data correctly on iOS? Case with NSUserDefaults

I'm making an app for iOS devices. It's not my first app but it doesn't important. My app use NSUserDefaults to store data which are using during application runtime. All works good while user wants to delete app. After this and after installing/compiling app again on same device all settings from NSUserDefaults are removed - It's look like app is first time on this device.
The question are:
How should I store data if I want to read it after removing and installing again an app?
If not NSUserDefaults then where to store this data?
Thank you in advance.
the nsuserdefaults are not preserved. nothing in your app's sandbox is BUT for the keychain. values in the keychain are not erased.
so use the keychain for values that you want to keep.
BUT don't store everything in there. normally when a user deletes an app he wants stuff gone.
the only other way I can see would be your own server where users can store backups, the dropbbox api or icloud
I think you could store defaults in your custom plist, and then use iCloud, which is built in iOS. iCloud will automatically backup documents from your app, and then you have them available on new installations since apple handles this.
Have a look at apple's official documentation about storing key value data on iCloud:
https://developer.apple.com/library/ios/#documentation/General/Conceptual/iCloudDesignGuide/Chapters/DesigningForKey-ValueDataIniCloud.html#//apple_ref/doc/uid/TP40012094-CH7-SW1
In that link they explain how to add key value data on iCloud to your app.
You want to use the keychain, docs here.
This is the only way on the device. Possibly you could use iCloud depending on exactly what you're trying to achieve.

Am I misunderstanding NSUserDefaults initWithUser?

What I expect to happen:
I create an NSUserDefaults object with a username (NSString of my choosing right?) and when I save defaults it saves those defaults for just that user.
What actually happens:
When I try creating NSUserDefaults for different usernames they are always saved into the same com.companyname.appname.plist file so it seems to ignore the per-user part and just save app-wide.
My Question:
Does this work on iOS or only OSX? What am I missing? Shouldn't I be getting a different plist file per-user? I reviewed the one .plist it does create in xcode and there's nothing in there that tells the default it belongs to a particular username.
Yes you are misunderstanding it, but really it's a badly named method.
Essentially it's to allow Apps that run as root (or superuser) to access the UserDefaults for other users.
In this case, user is a unix user, not some arbitrary partitioning name that you (the developer) chooses.
I am pretty sure, NSUserDefaults is for a app, not a user. It is the defaults for that app. Now it is upto you to model it to store preferences for multiple users. Say using a NSDictionary
NSUserDefaults combines values from different sources.
If you use managed applications in the enterprise, there will be preferences coming from the enterprise device management system.
The application itself will have its own built-in defaults.
On top of that, the application can read and set applications per user; these are stored in the user's library/preferences.
If you do nothing unusual in your app, the preferences from all these sources will be combined, and whatever preferences you save will be stored as preferences for that particular user.
And as a very very unusual special case, apps running as root and not as a particular user can access every user's preferences.

Resources