Is Core Data sqlite database in the documents directory automatically backed up by iCloud? - ios

I'm working on a project that requires the Core Data database to be backed up somehow so that the data won't be lost if user deletes and re-downloads the app.
In the iOS storage guideline it states:
Only documents and other data that is user-generated, or that cannot otherwise be recreated by your application, should be stored in the /Documents directory and will be automatically backed up by iCloud.
I wonder whether it means that if I put my Core Data sqlite database in the /Documents directory, it will get backed up automatically by iCloud?
If not, is there any simple solution for backing up the Core Data database? I just need the database to be recoverable after app being removed and re-installed. Syncing between devices isn't my aim here.

Yes, putting your database in the Documents directory will do exactly what you want: allow back up to iCloud without syncing to iCloud.
Syncing requires moving to the ubiquity container, but thats not what you want.
More information can be found in the Apple Technical Note which explains how to exclude a file from backup. Of course, for the backup to work, the user has to have set up their device to back up to iCloud.
Edit: Here is another helpful link: Apple's App Backup Best Practices section of the iOS App Programming Guide.

Related

Appcelerator getting a SQLite database to backup and restore with iCloud Backup

My app is live on the app store and users are reporting they cannot see their data after restoring the app to a new or reset iOS device.
The app uses a SQLite database created in the default Library/Private Documents folder by Appcelerator SDK.
I've set the remoteBackup = true flag on the database file, but I'm confused as to whether Apple even backs up from this folder, or whether the database needs to be in the Documents folder to be included in backup?
It should be noted that the database is likely to remain quite small, say 200-300Kb.
Has anyone employed a successful strategy to ensure locally stored SQLite data restores ok?

Best option For Syncing Documents Directory Between Devices

I want to keep an apps documents directory that contains sqlite using core data files in sync across users' devices. The sqlite files are the only files in the apps documents directory and simply need to be common to all users' devices
I've tried zipping up the sqlite files to send by email, which works with iTunes file sharing but is not suitable for my needs as it can expose the files to other users' devices.
I've tried using app groups to keep the directory common across devices http://blog.sam-oakley.co.uk/post/92323630293/sharing-core-data-between-app-and-extension-in-ios,
and
Accessing Core Data SQL Database in iOS 8 Extension (Sharing Data Between App and Widget Extension) but that simply did not share the directory across devices for me.
I've sent the file to parse, but pulling them down and reconfiguring the data was the problem there.
I've tried using iCloud and even the Apple engineer gave up on that one.
What I'm after is the simplicity of file sharing through iTunes (being able to replace the sqlite files) with a bit more finesse and without the need to plug in the device.
Some considerations
The whole model can be synced in one go
Data does not need constant syncing facilities, a manual sync option would suffice.

Should I follow iOS Data Storage Guidelines?

My iOS app is intended to be compatible with iOS 5.0 and above, and it has iCloud capabilities turned off in it's target settings, I'm not integrating with iCloud. My app stores an sqlite file and some image files into Documents folder. The sqlite file is not downloadable, but images are.
I've read some posts from people saying that their app's submission was rejected because they don't met the iOS Data Storage Guidelines, but I'm not sure if that is only required if your app has iCloud capabilities enabled, is it? Should I set the NSURLIsExcludedFromBackupKey for my files anyway?
Thanks in advance
EDIT
I've read this here:
It is not possible to exclude data from backups on iOS 5.0. If your app must support iOS 5.0, then you will need to store your app data in Caches to avoid that data being backed up. iOS will delete your files from the Caches directory when necessary, so your app will need to degrade gracefully if it's data files are deleted.
But I need the sqlite file to be in Documents to insert data... how should I handle this?
It has nothing at all to do with whether your app uses iCloud or not. It has to do with the user performing backups to iCloud which is beyond the control of your app.
If all of the data in your app that is stored in the app sandbox is data that is created and stored by the user through the use of the app then Apple will have no problem with the data being backed up.
They have issue with replaceable files being backed up needlessly. If the database file is read-only and could be obtained from a server or the app bundle then don't let it be backed up. But if it starts out mostly empty and then gets data added as the user adds data through the app then it should be backed up. Same for the images.

What directory should I store analytics data in on iOS?

I'm trying to store analytics data that is saved locally about a user's actions so it can be uploaded later when the user has an internet connection. I'd like the data to be stored locally and not deleted between subsequent opens of the app under normal circumstances. I do not want the data to be synced to iCloud. I'd also ideally like the data to be preserved between updates. It's fine if the data gets deleted in cases of low space.
I'm getting different answers from different sources about where to store the data- either in NSCachesDirectory or NSLibraryDirectory. Note NSCachesDirectory is a subdirectory of NSLibraryDirectory, eg. the filesystem looks like Application_Home/Library/Caches/.
According to the official documentation: http://developer.apple.com/library/ios/#documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/PerformanceTuning/PerformanceTuning.html#//apple_ref/doc/uid/TP40007072-CH8-SW9 implies I should use NSCachesDirectory to store the data and it is not deleted under most circumstances. It also implies NSLibraryDirectory is synced to iCloud.
According to these answers: How can I get a writable path on the iPhone?, https://stackoverflow.com/a/5444762/340520/, When are files from NSCachesDirectory removed?, NSCachesDirectory is not preserved between app updates and claims that I must constantly recreate the NSCachesDirectory. The first answer also implies NSLibraryDirectory is the best place to store the data. However those answers are two years old.
According to the documentation and this answer: http://developer.apple.com/library/ios/#documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/PerformanceTuning/PerformanceTuning.html#//apple_ref/doc/uid/TP40007072-CH8-SW10, https://stackoverflow.com/a/8830746/340520, NSCachesDirectory ARE preserved between app updates.
Localytics' iOS SDK stores their data in NSCachesDirectory: https://github.com/twobitlabs/Localytics-iOS/blob/master/src/LocalyticsDatabase.m
Mixpanel's iOS SDK stores their data in NSLibraryDirectory: https://github.com/mixpanel/mixpanel-iphone/blob/master/Mixpanel/Mixpanel.m
Between all these sources, I've been leaning toward using NSCachesDirectory, but I'm not confident that the data won't get regularly deleted under some circumstances.
NSCachesDirectory is the wrong place to store persistent information that you will need across app starts or even device re-starts.
To prove my point try this ...
Get a iPhone device that has only 8GB disk space.
Use your app to write a file in the NSCachesDirectory.
Start downloading random apps to fill up the disk space. Very soon you will see the Storage limit dialog shown by the OS.
Now just re-start your phone, start the app and see if you can find your file that you wrote.
If the first time you find the file, try the experiment again and you will find your file missing. During the device startup, if you see the device logs you will notice logs indicating purging directory to make space etc.
Use NSCachesDirectory to store information you can keep downloading from your server. Not information that you need to upload to your server.
The Caches directory should only be used for files that your app can easily replace if they are deleted. The Caches directory is may or may not be purged during an app update and possibly if the device runs out of storage space. Only use this for temporary files or files you can easily replace.
My first choice would be the Library/Application Support directory (NSApplicationSupportDirectory). Please note that this directory is not created by default. Your app must create it on first startup. This path is kept during app updates (like most of the app sandbox) and it is backed up via iTunes (or iCloud) device backup.
I think the best place is Library/Application Support (NSApplicationSupportDirectory) refer How do I prevent files from being backed up to iCloud and iTunes? for details.

Is iOS 5 iCloud Backup save webkit data for app using the storage of a UIWebView?

I have a phonegap iOS app using the sqlite DB of Webkit (through UIWebView), and I wonder if the sqlite data will be saved with iCloud Backup (iOS5). The sqlite data are stored in Library/WebKit folder. In the apple doc, they say:
The placement of files in your application’s home directory determines what gets backed up and what does not. Anything that would be backed up to a user’s computer is also backed up wirelessly to iCloud. Thus, everything in the Documents directory and most (but not all) of your application’s Library directory.
But it can say exactly which folder in the library directory are not saved. And I don't know how to access iCloud to check if the directory is saved
Library/WebKit is included in the backup. With the exception of Library/Caches, everything in the Library directory is backed up.
The data included in an iCloud backup for your app is identical to that included in an iTunes backup, so you can examine the contents by backing up to iTunes and using a tool like iPhone Backup Extractor to see what's included.

Resources