iPhone - NSUserDefaults perimeter - iphone

When setting values in NSUSerDefaults, may other apps that would know my used keys will be able to read my values ? I ask this because I can see that some values that are not mine are accessible, like NSArray* languages = [defaults objectForKey:#"AppleLanguages"];that I would had expected to find elsewhere.

I've just check it on my device - no, user defaults stored in one app are inaccessable from another app.
But as you said exist some system-defined values, that shared by system to all apps.
p.s. Otherwise it will conflict with one of the basic iOS paradigm - sandbox. One separate sandbox for every app.

Related

How to generate a good, non-changing UDID on an iPhone

In iOS 5 the usage of [[UIDevice currentDevice] uniqueIdentifier] got deprecated. We are now encouraged to use own-generated UUIDs and store them in the app's NSDefaults. That's OK for most usage, I guess.
But my question is - is it possible to generate somehow the UUID that would behave like the device ID right now - I would like to keep it the same even after the application is removed and reinstalled. The purpose of this is to help tracking possible fraud tries taken from the iPhone.
I'm wondering if usage of MAC-address, as with this category: https://github.com/erica/uidevice-extension/blob/master/UIDevice-Hardware.m would be OK?
The discussion for the uniqueIdentifier property in the documentation states:
Do not use the uniqueIdentifier property. To create a unique
identifier specific to your app, you can call the CFUUIDCreate
function to create a UUID, and write it to the defaults database using
the NSUserDefaults class.
Writing it to the user defaults should ensure that it is kept if the app is removed/reinstalled I would have thought.
Edit:
Sorry, they are not kept when an application is removed apparently. The documentation describes how to generate a UUID but I can't find out whether it is constant for a given user/device. I have seen some people proposing the use of keychain for persistence through app removal/re-installation but don't know how recommendable it is (and in any case the user can, I suppose, remove the entries).
Create your own UUID using the method described by Apple (the one pointed out by jbat), store it in NSUserDefaults.
Using iCloud you can then use the Key-value store to help 'persist' this UUID to a specific user, between installs and different devices.

How does iOS store persistent data with encryption?

Can an iPhone app encrypt its stored data? So that even a user with a Jailbroken iOS device cannot access the file. For example, game-center may sync with local data, you do not want the user manipulating the scores. You do not want your IAP be circumvented either.
Is there a simple way to encrypt your data before writing to the device?
Maybe my questions are not very clear. Indeed they are:
When I'm using things like: [array writeToFile:path atomically:YES]; is there any auto-encryption that ensures only my app can access the file correctly?
If not, what is the simplest way to achieve it?
PS: now I found NSData can do the job, but the NSDataWritingFileProtectionComplete flag requires #if __IPHONE_4_0 <= __IPHONE_OS_VERSION_MAX_ALLOWED. I wonder what happens on not-supported devices?
More information on iOS encryption in #GrahamLee's answer to this question and on other iOS tagged questions on security.stackexchange.com.
Basic summary is - based on iPhone controls alone:
If someone has the device and it isn't locked, they can access all the data
If someone has the device and it is locked, they can get most of the data, and possibly all (some exceptions may apply)
You could obfuscate, and use encryption within your app when storing data, but an attacker could reverse engineer that encryption code to decrypt.
You need to work out the value of such DRM techniques and decide whether they are worthwhile in this scenario.
That docs will help you to find more accurate answer:
http://sit.sit.fraunhofer.de/studies/en/sc-iphone-passwords.pdf
http://sit.sit.fraunhofer.de/studies/en/sc-iphone-passwords-faq.pdf

Determine which store (ie country) an iphone app was purchased from?

For business reasons the project I'm working on has the requirement to determine which country's itunes store an app has been purchased from.
Knowing where the user is at the time of purchase (via location services etc) is not suitable and they would prefer to have 1 universal binary rather than having to have a separate binary for every store.
Is this something the application can determine at run-time?
Note: the specific answer is NO. You can NOT get the app store country. (As of mid-2010.)
For general readers, the following could be useful ... it is quite a nuisance to collect exactly these code three fragments together:
// to ("usually") get the preferred language from those we supplied in bundle
// [[[NSBundle mainBundle] preferredLocalizations] objectAtIndex:0]
// to ("often") get the preferred language regardless
// [ [NSBundle preferredLocalizationsFromArray:[NSLocale ISOCountryCodes]] objectAtIndex:0]
// to ("fairly reliably") get the user's chosen language setting...
// [ [NSLocale preferredLanguages] objectAtIndex:0]
Cheers
Have you tried hidden using in-app purchases to determine the store?
Hmm, could this be regarded as a violation of a customers right to privacy? I would imagine you have already looked at the reporting done back to you from the app store. If it's not in that data, I would imagine you won't be able to get it.

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.

Do NSUserDefaults persist through an Update to an app in the Appstore?

Is this the case? Do NSUserDefaults get reset when you submit an update to an app on the App Store, or are they reset?
My app is crashing when updated but not crashing when downloaded fully - so I'm trying to determine what could possibly be different in the updated session to the freshly downloaded session.
Cheers,
Nick.
They are usually not reset unless the user deletes the app. For basic data, NSUserDefaults is the best way to save data such as preferences, dates, strings etc. If you are looking to save images and files, the file system is a better bet.
I beleive the answer is YES, it will persist. This also fully documented under the Application Directory chapter in the Apple iPhone OS Programming Guide.
Direct answer to the posted question: YES.
Your problem:
Your app gets crashed due to logic issues. Suppose you store an object in defaults and the app checks it's value on launch (or elsewhere). In you update you could change the way it is checked or used, e.g. you expect a value, but the object is nil, or vice versa. This may cause a SIGABRT or EXC_BAD_ACCESS.
If you had CoreData model and you changed something in your model and update, without managing migration, thats probably reason why your app crashes on update...
I have a similar experience. Our app stores a version number in Settings.Bundle/Root.Plist. This gets displayed through the iPhone Settings app. What we find is that on an Install the version number gets loaded from the app bundle - therefore the version number is correct. On an update however the version number doesn't change. This gives the impression the user is running a previous version of the app. We don't have any logic linked to the version number, it's just for display (it could be used by contact centre staff when diagnosing faults).
Our experience is NSUserDefaults doesn't get cleared when a user updates our app, but the Settings display doesn't get updated either.
Be aware of this case, when your app is running in background and you cannot access your stored values in NSUserDefaults:
Eric:
There have been many threads and bugs about this, but it's happening to me again in ios 9. I have an app that launches in the background in response to NSURLSession tasks and content-available pushes. Reproducibly, if I reboot my phone and wait for a background launch of my app to happen, then when I open the app I find that [[NSUserDefaults standardUserDefaults] dictionaryRepresentation] contains all the system values, e.g. AppleITunesStoreItemKinds, etc. but does not contain any of the values I have set. If I force-quit and relaunch the app all of my values come back. Is there any way to avoid it caching the "empty" standardUserDefaults from before the phone is unlocked, or at least to determine when they are messed up and fix them without having to force-quit the app?
Eskimo (eskimo1#apple.com):
The problem here is that NSUserDefaults is ultimately backed by a file in your app’s container and your app’s container is subject to data protection. If you do nothing special then, on iOS 7 and later, your container uses NSFileProtectionCompleteUntilFirstUserAuthentication, a value that’s inherited by the NSUserDefaults backing store, and so you can’t access it prior to first unlock.
IMO the best way around this is to avoid NSUserDefaults for stuff that you rely on in code paths that can execute in the background. Instead store those settings in your own preferences file, one whose data protection you can explicitly manage (in this case that means ‘set to NSFileProtectionNone’).
There are two problems with NSUserDefaults in a data protection context:
Its a fully abstract API: the presence and location of its backing store is not considered part of that API, so you can’t explicitly manage its data protection.
Note On recent versions of OS X NSUserDefaults is managed by a daemon and folks who try to manipulate its backing store directly have run into problems. It’s easy to imagine the same sort of thing coming to iOS at some point.
Even if changing the data protection were possible, NSUserDefaults has no mechanism to classify data based on the context in which you’re using it; it’s an ‘all or nothing’ API. In your case you don’t want to remove protection from all of your user defaults, just those that you need to access in the background before first unlock.
Finally, if any of this data is truly sensitive, you should put it in the keychain. Notably, the keychain does have the ability to set data protection on an item-by-item basis.
Source:
https://webcache.googleusercontent.com/search?q=cache:sR9eZNHpZtwJ:https://forums.developer.apple.com/thread/15685