sqlite db export from ios app cleanly - ios

I need a solution for a feature in an app my company is building. It is an IOS app for iPhone and iPad and we support ios5 and above only.
The end result we need is for the user to tap a button inside the settings area that dumps the apps internal database cleanly, attaches it to an email for the user to then address to whoever they wish.
Attaching to an email is not an issue. What I am concerned about is if it is reasonable to think that exporting a copy of an sqlite database to an email as an attachment would leave the user with a usable copy of the database. My customer base is not good about doing backups but the data is nevertheless very important to them.
Will a hot export of an sqlite database be usable, i.e. is this supported, or will the database be corrupt sometimes/always?
Keep in mind that all this function has to do is make it so that a usable copy of the database gets off the device and stored safely offline so that I can then walk them through restoring the database by copying it back into the device using iExplorer or PhoneView.
In the future we plan to add a robust export and import feature, but for now we are looking for a solution that we can implement in a day or less.
Thanks in advance for anybodys input and gasp some objective-c code that would dump a clean copy of an sqlite database in such a way that the database will be usable and not corrupted.

You don't need to make a hot copy of the database. When the user chooses the backup feature of your app, close the database, copy the file, and then reopen the database. You can now attach the copied file to the email.
I have a feature in my app for doing just this. I've never had an issue with a corrupt database file. As long as there are no active transactions running, the sqlite file should be OK to copy, especially if there are no open handles.
Another option would be to use the sqlite3_backup_init and related functions to copy the database.

Related

Copying Sqlite database file content in CoreData

I'm working for an iOS app that was earlier developed using phone gap. It is having a sqlite database for storing data. But now while developing the same app in native, I'm using core data for storing the data.
Now when the new native app replaces the old phone gap app on user's device, I want to copy data from already existing sqlite file into core data.
So when I run the application on device with phone gap build pre installed my app(native) replaces the old build as I'm using same bundle ID but I'm not able to find out the path to that sqlite file. Does sqlite file still exists in documents directory?
If you have an example old database file still installed on one of your devices you could try downloading the App off the device using the Device manager in Xcode.
Then you open up the bundle and search for your file. Then if you know its location / name you can simply access it, read it using some SQLite library and load the data into your CoreData backing store. Keep in mind you either want to mark it in NSUserDefaults or delete the old DB all together so your app does not keep on migrating ( And then maybe accidentally deleting new data from a user. ) I would choose for keeping the old one around for at least a version or 2 so you can verify that your migration works without bugs / deleting user data in the process.
Tip: It is probably a good idea depending on how big your database is to show the user some kind of progress or "migrating / optimizing db" while you're doing this. So you don't end up with the user adding more data to the database before you're done migrating.

Backing up sqlite DB on iOS

I would like to make backup copies of my app's main sqlite DB while my app is running.
1) I have read that it is safe to just copy the sqlite file if the DB has been checkpointed (at that point the wal file contains no important data). Does [managedContext save:] do that checkpointing, or is there something else I have to do? (ref -shm and -wal files in SQLite DB)
2) Is there any way, short of tearing down the whole core data stack, to be sure that core data doesn't try to write to the sqlite file while I'm copying it? My app does save frequently after any user input, and it would be nice if there was some way to force that to block for a second.
I have uploaded a sample app that provides backup and restore capabilities a number of different ways, including local backups, copy backups to and from iCloud, email backups, import from email, and file copy via iTunes. See link below for video demonstrating these capabilities and you can download the sample apps from the site.
http://ossh.com.au/design-and-technology/software-development/sample-library-style-ios-core-data-app-with-icloud-integration/sample-apps-explanations/backup-files/
EDIT
It should be safe to create a new persistentStoreCoordinator with the same fileURL and to then use migratePersistentStore API without closing the App, save the main MOC first though. I always use JOURNAL=DELETE mode to ensure I just have to use a single file to deal with. If you are using WAL mode then you would need to backup all three files used by sqlite.
Regarding 2)
When I make backup, I close all mom's, moc's and persistent store. Then it's safe to make backup or restore. Also all views are waiting for events to release all coredata resources and bring them back when database is available again. It's good to have a singleton to manage coredata.

Updating an iOS app on the AppStore which uses CoreData

I know there are similar questions on this subject but nothing that quite answers my query. I am aware that it is a bit of a newbie question!
I have an app on the AppStore which I will soon be looking to update. My binary contains a pre-loaded sqlite file with a list of data which the user starts off with. However, the user will extensively edit this information and it is crucial that that data is maintained through the update.
I am not changing the CoreData structure at all so won't be performing any migration but my concern is that when I upload the new binary the packaged sqlite file will overwrite the users existing data. I suspect that won't be the case but can anyone shed any light on it?
When updating an application the documents directory is untouched. Presumably your startup code checks to see if you have already copied the initial database from the bundle to the documents directory - this will work the same way after an upgrade.
You are testing this every time you run a new build on your device during development anyway - you've put a whole new version of the app bundle on there, and it doesn't kill all your data, does it? (does it???)

iOS CoreData image problems when working from a backup

We have an app that allows users to create their own content, it includes "groups" of text and images which are then used in a game. They are written to the db, but also "restored" back to documents when they are "synced" or "backed up" to an existing or "clean" device.
A user is able to backup (.fgz) to a dropbox, which is meant to make it easy to share the game data between a number of devices. This works without any problems. The game content (db driven) and images can be shared to any number of devices without any problems.
Every time we update the App, we have a problem where the text entries are retrieved and are completely viewable (both from the local file system / sqlite) but for some reason the images in the same location will not display as they have previously (the path to the image seems to be deprecated during the update). This includes doing a "backup" to a newer version of the app, to a device which has not previously had the application installed, which is also really strange.
During testing, using Xcode and local copies (replicating "install in place", we can not replicate this problem using the exact same code, and databases. There are no errors or warnings. Is this a core data problem? Any other suggestions about what we might be doing wrong?
What is going on here? We are at our ends trying to find a solution. Is there a better way to do this? We have thought about keeping our files as part of the local file system only, but if we do this, they won't be as "shareable" via the dropbox.
Any thoughts about managing image data in iOS would be very much appreciated.

Shipping an iOS app with a read-write enabled (also pre-filled) sqlite database

This is the first time I'm developing for iOS. I need my app to ship with a pre-filled sqlite database which a user will read from and write to. How should I go about deploying this? Can experienced developers help me?
What I thought was this:
I create and pre-fill the database in my development machine, add it to my app bundle. During app initialization in device, I check if I have a database in NSDocumentDirectory of my app. If not, I copy the database in the bundle to NSDocumentDirecory and read from/write into it. If I have a db there, I just use it.
Is this a bad idea? Any pitfalls I'm falling in here?
I have an app that does something pretty similar to that. Mine doesn't allow writing to the database, but I don't see why it would be hard.
I have a dataset that I import into a SQLite database, copy it into the apps directory, put the DB filename into a constant and it seems to work really well.
I change the SQLite filename each time I put it in there (MyDB62020111.sqlite -> MyDB62020112.sqlite) just to make sure that I avoid a problem where it thinks that the file is already in the NSDocumentDirectory and not update it.

Resources