I store the device token value with NSUserdefaults, and then, send this value to my server.
My app checks if this value exists or not.
If the value doesn't exist, my app tries to call the registerdevicetoken method.
But I found out an issue.
If a user restores his/her iPhone via iTunes, the NSUserdefaults values are recovered.
However the stored device token is not a valid device token for a new device, but my app can't recognize that the phone has been reinstalled via iTunes.
How can I collect the correct device token, when users restore their iPhone?
Okay. Let's take the document's folder approach. Firstly, let's take a look at the anatomy of an iOS app. As you see below there are 3 key folders.
The complete Documents and Libray folders get backed up, unless you specifically call a command on a file not to. That's what we will do. Create a file that you can call firstLaunch.txt for example. Put this file into Library/Application support/. And set the noBackUp tag using:
-[NSURL setResourceValue:forKey:error:] using the NSURLIsExcludedFromBackupKey key. This will prevent the file from backing up. Now, you can have a simple if-else statement checking if the file exists. If it does, that means that the app was already run and the token is up to date. If it does not, create a new user token and now create the file again, put it into the correct folder. To be clear, this is the only time you should be creating the file, as it will only get called on the first launch and after being restored. You can find more info and this image at the Apple Docs.
Hope that helps, Julian.
Related
I worked on app in which user can add images and make notes about those images, which i stored in sqlite and i store cards in document directory. I have enabled file Sharing option in app so user can keep backup of app's data manually in her PC via iTunes.
Please consider this scenario: the user connects the device from time to time to iTunes, and the synch process takes place. however, she does NOT go into the File Sharing option which is one way to backup manually the data in PC. now, she drops the phone in the bathtub and it does not work or due to some other reason she lost her device.
my question: when she gets a new phone, can she recover her data?
if yes, then how could we do this?
if no, then what is the correct way now to backup the third party app data.
My app is going to save a flag in the database (core data) saying whether the user is authenticated or not. How easy or difficult is to someone to access the "core data" database and change the information there without going through the App?
I am going to save a flag there saying "this user is authenticated" so he never has to authenticate again. This is a fun app, not a bank app, so I wonder if that's ok.
Putting in other words: Should I assume that a regular iPhone user (not jailbroken of course) will not be able to mess with the "core data" database and this database can only be accessed through its intended iphone app?
This isn't the kind of thing you should use Core Data for anyway. You should instead use NSUserDefaults or the keychain (depending on if you're just storing that flag, or associated user/password information).
The user defaults are there for storing settings, the keychain for private data. Use the right screwdriver for the right screw.
The iOS app sandbox is quite tight on-device. As such other apps won't be able to access your database, nor will the user on-device.
Application data in the app's Documents directory is backed up through iTunes, however. Though I've never tried such a thing, I can imagine a scenario where the user installs and runs your app but is not authenticated. He syncs and the user data is written to his computer. He opens the backed-up resource on his PC (iTunes does encrypt or obfuscate it) and figures out how to change the sqlite database or plist to show himself as authenticated. He then uninstalls the app on his device, then reinstalls it through iTunes, authenticating himself.
If the scenario is possible, you could potentially store the database in the cache directory instead, a directory that's not backed up when the device is synced with iTunes. It means the database would vanish if the user had to restore his device, but that might be an acceptable loss in your scenario, I don't know.
Edit
I agree with jer that the database isn't the best place to store such info, and if you're targeting iOS 3.2 and above, keychain is definitely the better place.
I don't believe a user on a non jailbroken phone would be able to mess with the data.
When does data get restored for an app? What if I save data in the app's document directory. Then they sync with iTunes. Now iTunes has a backup. Will that data be populated to another device when they sync that new device to their iTunes or will they just get a clean install of my app? I'm trying to figure out how to keep track of a subscription in app purchase and was wondering if I could keep record in NSUserDefaults or some other local store.
Backups are per-device. So a backup of your iPod will not be restored to your iPhone. In other words, there is no sync.
Many times iTunes fails to create complete backup of all the iPhone data say it be contacts, message, mails etc. This type of problem may occur due to not installing iTunes properly. So, you should check whether iTunes have been installed correctly or not. In case there is no problem with iTunes then it is possible that you are trying to create backup of the files which can not be backed with the help of iTunes. To overcome with this issue you need to make use of iPhone backup application. By using this tool you will be able to prepare backup of all the files within minutes safely.
If the user backs up to iTunes, and then restores their backup to another device (maybe they lost their original iPhone), the contents of the app Documents directory will be put on the new device. Anything in the tmp folder won't be backed up or restored like this, but the Documents folder will.
However, that's not the best way to store the in-app purchase information. You should be storing that on your own server and keeping a count of the number of times the purchased content has been used. Inform the user that they can use it a certain number of times (say three) and after that they will have to buy it again. I'm not exactly sure of any details beyond that (like how to verify their identity) but it should get you started.
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
I have an app that is running in the simulator. I read and write from a sqlite3 data source. However, if i restart the app, then all datg that i had previously wrote to the db is lost.
The data is always in its original state.
Now back when i was developing this app i thought i read somewhere that data can not be persisted via iphone simulator.
Can anybody confirm or deny this?
Thanks!
You need to place your db file in a writable place, e.g. in the Documents folder. All the bundle files are read-only files.
If you are distributing an initial database with the app, you will need to copy it to Documents (or another folder) and use the copy.
You also need to ensure that you close the database connection in your application is closing (i.e. you receive a applicationWillTerminate message).