Trying to overwrite sqlite database in iPhone app update - iphone

Unlike most sqlite apps where developers don't want to overwrite data in a sqlite database, I'm trying to enable an app to overwrite all data with future updates. The sqlite database will have the exact same name and have the same tables, I just want to be able to update the data contained in the database without making users delete the app and reinstall it. Is there an easy method to do this?
Thanks in advance!

A SQLite database file is just a normal file, so no special steps are needed. Get the path or URL to the file, and use NSFileManager's -removeItemAtPath:error: or -removeItemAtURL:error:. Then create the new database the same way you created the old one.

Related

Pre Populate Core Data By Copying .sqlite File From Documents

I have read that this works, but I can't get it to. I want to pre populate Core Data. I ran my project so it would create the sqlite file. I copied that to my desktop and then prepopulated it using the command line, sqlite3. I ran queries to make sure it was populated correctly. So now I re-add it to my project. No matter what I do, though, it won't fetch the data.
I got it to work ONCE. I re-copied the sqlite file from my project's document folder after running it in the simulator. I then populated this new sqlite file. I put it back in my project and I got the contents to display.
I think the problem is the Z_METADATA table. This table has a Z_UUID attribute. I think the only time it worked was when the simulator's UUID and the sqlite's Z_UUID attribute were the same.
I went into ~/Library/Developer/Xcode/DerivedData and deleted the contents of the DerivedData folder. So now my simulator will have a different UUID when I run it. I did this and now the contents of the sqlite file will not display. This is why I think the Z_METADATA table is the problem. The Z_METADATA's UUID and my simulator's UUID are not the same so for some reason it can't use it?
All the articles about pre populating Core Data this way I found are old, around 2009, so I don't think this was a problem then. So can I use this method of copying the sqlite file, using the command line to pre populate it, then re-adding it to the project? Does anyone have a current way to prepopulate Core Data?
So the error is that my NSFetchedResultsController is returning a count of 0 objects. I got it to return all the data the one time I mentioned above.
According to the Core Data Programming Guide,
Important Although Core Data supports SQLite as a store type, the store format—like those of the other native Core Data stores—is private. You cannot create a SQLite database using native SQLite API and use it directly with Core Data (nor should you manipulate an existing Core Data SQLite store using native SQLite API). If you have an existing SQLite database, you need to import it into a Core Data store (see “Efficiently Importing Data”).
While I'm sure someone has reverse-engineered the Core Data sqlite format, Apple does not provide any documentation, and it is likely to change across across major OS releases.
Write a command-line app that uses Core Data to do your import.

What is the behavior of an application when upgdraded at appstore

I wanted to know something which is very disturbing for me. i.e.
Lets say I have an App. which is in the Appstore and running fine.
This App. has a local database with lets say 5 tables.
I update this App. and add 2 more new tables, which makes it a total of 7.
When the previous app version users will upgrade to the newer version. Will the database be updated also for the previous version users ?
If yes ?
then will the previous data will be removed.
If not
then the code will obviously make some crashes as it is going to need the new things which are not replaced.
Waiting for your precious comments.
It will all depend on your database. If you are using CoreData, you can migrate the users data into the new database and structures. All the information for your data model is stored in the .xcdatamodel class for your project. It isn't bundled into your code the way other files are.
The part you would need to look into is the Model Versioning Identifier. Here you will be able to increment your MOM, Managed Object Model.
You can also migrate the data over as well. I would review Apple's documentation on CoreData with focus on versioning and migration. Good luck.
Apple Core Data Versioning
If the database is based on coredata then you will need to use .
But if you are using sqlite DB
Then you can save the version number of your app into your db and whenever database is called(with new installation/upgrade), compare the version against the expected version If new version > older version then change the schema (this is needed if you would have changed the schema of your database) with using SQL ALTER statements and update the app version number. so whenever user is going to update or fresh installation, it will check the new version with your older version,
if it differ then
update schema,
and if its same
no need to make any changes.
If you would not have made any schema related changes (for example adding new column..) then you do not need to worry, user will not lose the data.
The contents of the documents directory is left unchanged. The contents of the .app bundle is completely replaced with the new version.
If you store your database in the documents directory and it is modified by the application, you will need to perform some migration to upgrade to the new version. If it's just a read-only database, you can copy over it with the new database.
It depends on where database is placed. All files in application bundle will be replaced. Files in Documents directory will remain intact unless you overwrite them...
Where do you store your database?
What i consider a good approach is to place database in bundle then on first run copy it to documents directory so that you gain RW access.
In your updated application you can check if database exists in Documents read it and update tables to new version, if not then just copy file from bundle to new location.

Does data base change with new update iPhone app

I have a program that my user save something on it. I want to release new version.
My question is: if my users update their app, will their data still be there or not?
My new release its not part of database.
When you update an app, the data is preserved. As far as I am aware, the process is the same as when you test a new build from Xcode.
The only time this could be an issue is if you are using CoreData, and you update your model. In this case, the old store will not work with your new model unless you migrate the old store. Apple has documentation on migrating CoreData stores here.
The database will be in sandbox of the app. So until user deleted the app the database will be there. You can upgrade the app. But if there is something changes into database then you again need to copy the new database to documents directory either by installing the app again and remove the older version Or by manage through code.
All contents of the Documents directory on device is preserved, update only replaces the application bundle, which is read-only anyway.
Can you please let us know for saving what kind of data model you are using, whether Core Data stack or SQLite. If you are using one of them, its pretty obvious you have to write and fetch your DB from documents directory. If your new version does not contain one, it wont work either.

sqlite DB to-do during iphone app update

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.

How to dynamically create a sqlite3 database on the iPhone?

I would like to know if it is possible to create the file of a database by programming?
Actually I need to create a database if it does not exist.
I'll assume you have your own valid reasons for using sqlite3 directly rather than Core Data. There are certainly cases where it's appropriate.
The sqlite_3_open() function will create the database if it doesn't already exist. The sqlite3_open_v2() function will create the database if you pass SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE in the flags parameter. See the documentation for more details.
Of course on iPhone you'll need to make sure you're creating the database in a read-write directory such as the app's Documents directory, as opposed to the Resources directory, which is read-only.
In practice I've never tried building a database from the ground up on the iPhone. I always found it simpler to just include an empty DB file with the schema pre-built as an application resource, and then copy the file to the Documents directory the first time the app is run.
Are you sure that you need to create the database file directly? Maybe you should check out the Core Data Framework.
Thanks for your answers, I have never used Core Data so I will have a look on this.
For the moment I also copy a DB file from the Resource directory to the Documents but I would like to create a static library which can be used by many persons. So I would give a minimum of files to add to their project. That's the reason.