I know I can set a Pre-Populated SQLite file as CoreData persist file. But When I update my app version, and the Pre-Populated Data need be updated, I wonder if there has another way to do that except CRUD the new Pre-Populated data by codes after the new version launch.
You can pick the pre-populated sqlite file as a source file in the persistentStoreCoordinator but keep in mind that if you update de data, the user generated content will be lost...
In one of my project I have also faced a similar problem. My approach was that.
Create 2 configuration in Core Data. One for static data and second for dynamic data.
While configuring your persistantCordinator set two separate SQLite files corresponding CoreData configuration.
There is not extrac coding effort other than setting up two separate DB in persistantCordinator level. Everything else will be managed by CoreData like. Reading, Writing etc.
For static database keep a DATABASE version of your own. When your static data changed increase this database version and in App launch check the existing database version with this new version. If new version is greater copy and replace the existing static database.
With this approach you have the following benefits.
You wont lose your dynamic data.
You need to change the static database only when there is a change in static data.
Hope this helps.
Related
I have some general questions about iphone app updates that involves sqlite db.
With the new update does the existing sqlite db get overwritten with a copy of the new one?
If the update doesn't involve any schema changes then the user should be able to reuse the existing database with their saved data, right? (if the existing database doesn't get overwritten from 1 above )
If there are some schema changes, what's the best way to transfer data from the old database into the new one? Can some one please give me guidelines and sample code?
Only files inside the app bundle are replaced. If the database file is in your app's Documents directory, it will not be replaced. (Note that if you change files inside your app bundle, the code signature will no longer be valid, and the app will not launch. So unless you are using a read-only database, it would have to be in the Documents directory.)
Yes.
What's best depends on the data. You're not going to find sample code for such a generic question. First, you need to detect that your app is running with an old DB version. Then you need to upgrade it.
To check versions:
You could use a different file name for the new schema. If Version2.db does not exist but Version1.db does, do an upgrade.
You could embed a schema version in your database. I have a table called metadata with a name and value column. I use that to store some general values, including a dataversion number. I check that number when I open the database, and if it is less than the current version, I do an upgrade.
Instead of creating a table, you could also use sqlite's built-in user_version pragma to check and store a version number.
You could check the table structure directly: look for the existence of a column or table.
To upgrade:
You could upgrade in place by using a series of SQL commands. You could even store a SQL file inside your app bundle as a resource and simply pass it along to sqlite3_exec to do all the work. (Do this inside a transaction, in case there is a problem!)
You could upgrade by copying data from one database file to a new one.
If your upgrade may run a long time (more than one second), you should display an upgrading screen, to explain to the user what is going on.
1) The database file isn't stored as part of the app bundle so no, it won't get automatically overwritten.
2) Yes - all their data will be saved. In fact, the database won't get touched at all by the update.
3) This is the tricky one - read this fantastically interesting document - especially the part on lightweight migration - if your schema changes are small and follow a certain set of rules, they will happen automatically and the user won't notice. however, if ther are major changes to the schema you will have to write your own migration code (that's in that links as well)
I've always managed to get away with running lightweight migrations myself - it's by far easier than doing it yourself.
What I do is that I create a working copy of the database in the Documents directory. The main copy comes with the bundle. When I update the app I then have the option to make a new copy over the working copy, or leave it.
please explain me next information.
I have app with CoreDataModel1, and now I create CoreDataModel2. And I need to use CoreDataModel2 in my app. I read about migration and ti's work fine. But I don't need the previous data from CoreDataModel1. How I should do this. When I make migration all my previous data copy to CoreDataModel2 but I don't need it.
Normal Core Data migration doesn't need this, because there is no copy. The migration process updates the persistent store file to use the new model, keeping the same file. There's no old file to delete.
If you have implemented a custom migration scheme that does copy the data to a new file, then you're on your own. You remove whatever old file(s) your scheme leaves behind that you don't need any more.
The way I understand your problem, you do not care about the old database file or data. In this case, you might just create a new model with a new persistent store url (i.e. file name) and ignore the old one.
The standard way is to simply select the second model version as the current one, switch on
NSMigratePersistentStoresAutomaticallyOptionand
NSInferMappingModelAutomaticallyOption,
and if need be delete old data upon startup.
i have submitted an app on the app store that uses core data.
The problem is that i duplicated my project and then lost the first source code. If i update the app using the "duplicated" source code does it delete all core datas users may have stored? i know that if you change the file file-xcdatamodel without mapping the previous datas you will lose all you had stored, can i assume the duplicated project use the exact same file?
thanks in advance
In that case I think that, if you didn't modify your xcdatamodel, the data stored by user will keep during the upgrade. In order to be sure, you can install your own apo from App Store, save some data, update this app from Xcode with your new version and check if the stored data still are there.
If you've modify your xcdatamodel, you must perform a light or a heavy migration, depending on your canges.
I am updating an old iOS app which used sqlite database. I changed the database structure adding columns to existing tables. Now, I am testing it on my device. If I clear my old app from iPad and then run this new updated version on it, it is working fine. But if I have the old version installed on ipad already and test this updated version, it is somehow using the old database instead of the one updated. Can some one help me why it is doing this?
My guess and to try and make a simple answer for you is this. It's likely you updated the database in the project file - which means when you run it, your new db will exist in the bundle. files in the bundle cannot be updated, so its common practice to copy the database out of the bundle and store it somewhere in the ios sandbox. I usually use the documents directory to keep it simple.
Most likely what is happening is that when you run it over a pervious install, it see's that the file is already copied over to the device so it does not touch it, however on new installs, it probably sees the database is missing so it copies it there and that is why on new installs it works fine but existing ones it does not.
Look in the app delegate or your root view controller for code that checks for the existing database and copies the database over if needed on startup.
If you need to update the database on existing installs, you would need to force the copy.
Beware though if you have data in the existing database not to overwrite it if its important. If important data is stored there, you have to either do a little shell game of getting the data and importing into the new database, or maybe a simpler way, is to run the database schema modification commands on the existing database so it is the same.
again, beware and make a copy of the local database file before you run those commands, just in case.
best of luck
In iOS, a SQLLite database is really just a file. When you used the old app, it created the schema in the database file. When you load the new app, the data remains, untouched. If you want to use the new schema, you will have to detect the old schema and update the existing data. I believe that there are documented ways to deal with this. Bryanmac's question reference seems to be a good place to start.
When you install a new version of your app, iOS actually installs it in a new directory and then copies the contents of the documents folder from the older version to the one in the newer version. If you want to just use your new db, the best way is to have this db renamed or stored in a different directory inside your app's document store.
Here's a relevant article on updating An sqlite CoreData backing store on iOS:
http://www.musicalgeometry.com/?p=1736
I have the task to re-engineer an iPhone app which makes use of Core Data to store some values. Unfortunately I do not have access to the original source code but I do have acces to old database files, copied directly from the device where the old version of the app is installed.
I have to create a new version of the app with some new functionality and I am trying to import the data from the Sqlite Db and migrate it to a new version.
I am already failing at the task to read the data from the old database. Though I can open the Sqlite file and such was able to exactly reproduce the data structure in my own datamodel, everytime I try to read the data, it fails with a
Can't find model for source store
error.
Ignoring the old data is not an option because there is important data stored there.
I googled for solutions and tried every recommended solution related to migrating data but it all fails. Maybe I can not use the Sqlite created by another app? Or so I overlook something in re-engineering the structure of the datamodel even when I used exactly the some field names and datatypes? Is there another way around this?
I could not solve the issue but I found a workaround. By using Sqlite directly, I was able to query the legacy data and import it into my newly created data model. A good starter point for using Sqlite is here:
http://www.techotopia.com/index.php/IOS_4_iPhone_Database_Implementation_using_SQLite