My app is crashing when ever i change the data model. Inorder to run it again i should delete the app from simulator and the run it. Instead of doing this is there any means that we can run the app without deleting whenever we change the datamodel. i want the previous data to be used. Thanks in advance
The answer is a bit tricky but this always works for me. This is for a clean installation of a new compatible .sqlite file, not a migration!
launch simulator, delete the app and the data (the popup after you delete the app).
quit simulator
open X-Code, after making any edits to your data model
if needed update the datamodel version:
Editor > Add Model Version...
set your prefs in the dialog that appears (counting up is preferable)
click on the {appname}.xcdatamodeld then in the far right pane
click the left icon of the 3 icons on top of the far right column
under Versioned Core Data Model select the one you just created
delete the {*appname*}.sqlite file (or back it up, remove it from project folder, and delete reference)
clean the app (Product > Clean)
Run the app in a simulator (for this tutorial I will assume 4.2)
While the simulator is running, in a Finder window, navigate to:
{*home*} > Library > Application Support > iPhone Simulator > 4.2 > Applications > {*random identifier*} > Documents > {*appname*}.sqlite
Copy this file to another location
Stop running your app in X-Code
Drag and drop the {appname}.sqlite file into the files list in X-Code.
In the dialog that pops up, make sure the copy to folder checkbox, is checked.
Product > Clean
Then run the app in the simulator again
Now you should have a working sqlite file!
Cheers,
Robert
Basically you need to be able to migrate existing data to the new schema -- read up on Core Data Versioning and Data Migration.
The file being used for NSPersistentStore can only correspond to one version of a Data Model at a time. You need to either do a migration of the data to the new version or tell your application to delete the persistent store file each time you start (for development purposes only).
Just saw that you want to keep your old data. You can try serializing your data to a NSDictionary and then saving it to a plist/json/xml file. Then, when your program starts you can delete the old NSPersistantStore file and create a new one. Import the data from the plist/json/xml file to the new empty persistent store file.
Remember, in order for light migration to work you need to keep the previous version of the data model in addition to the new one. Core data needs to know both models, past and present, in order to perform a migration.
I have the same problem and I haven't fixed it yet. I don't care yet. While my app is in development I just clear the data every time I change the model.
I think to use Lightweight Migration, you still have to make a copy of your data model for every version of the data model you want to migrate from or to. It's lightweight, but not lightweight enough for when you're changing your data model frequently in early development.
I suggest you catch the exception it throws when it can't load the data, and have your program automatically delete the data in that case and recreate it in an initial state. It's the same as the ignore the problem answer but you don't have to manually delete the data every time. You probably ought to leave that code in for production, as a backup in case migration doesn't work for some reason, but maybe you ought to ask the user if they want to delete the data.
Related
Here I've got a question concerning releasing update of the application in app store.
Suppose I've an application installed on my iPhone, which has some database inside, i.e. overtime user has entered info and the data were kept locally.
If the new version of application is released, and installed on my iPhone. Will the database be lost ?
I suppose all the information of the application, is removed and the update is installed like a new app. Please confirm.
Thanks
No the users data will not be lost.
When you update an app only the bundle data will be updated, meaning the .app directory of the installed app. Any other directory, like Documents and Library will not be touched.
If there is any data in for example the Documents directory that need updating then you have to write code to detect that and make the necessary changes.
If the database is used by Core Data then you will need to version and migrate the data.
All the files stored inside your app's documents directory (which is usually where db file is stored) are preserved during app update.
If you would have set the version number to your database for your iphone could have been easily handle, save your version number into your db and whenever database is called, compare the version against the expected version If new version > older version 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.
my guess is that it would not be replacing any of the existing files instead just updating them if any changes....the best example of data is not lost is that.....i usually update most of my games. and they do preserve my highscore even after the updates.. lol! So, go on. Nothing will be lost. Nice question though. :)
I am working on a iphone application project. we have released one application with a coredata model, now in our new release we like to remove the old one and add a new one. (we are not storing any user values on existing core data model). we forgot to remove the xcdatamodel from our application folder, but we removed all code relate to core data. Now we have to remove xcdatamodelfile and its related h and m class.
in our new project bundle can we create a new core data model and submit that application? i like to know this new xcdatamodel will create any problem for the users while updating our new release?
thanks!
Ram
in our new project bundle can we
create a new core data model and
submit that application?
Never forget to make a complete rebuild after changing the datamodel, as the build process sometimes does not correctly recognize datamodel changes
i like to
know this new xcdatamodel will create
any problem for the users while
updating our new release?updating our new release?
As you do not need any old data/migration create the persistent store in a new location and the old model/old data file will not be a problem at all. (given the model has been properly replaced by the new one)
The answer is a bit tricky but this always works for me. This is for a clean installation of a new compatible .sqlite file, not a migration!
launch simulator, delete the app and the data (the popup after you delete the app).
quit simulator
open X-Code, after making any edits to your data model
if needed update the datamodel version:
Editor > Add Model Version...
set your prefs in the dialog that appears (counting up is preferable)
click on the {appname}.xcdatamodeld then in the far right pane
click the left icon of the 3 icons on top of the far right column
under Versioned Core Data Model select the one you just created
delete the {appname}.sqlite file (or back it up, remove it from project folder, and delete reference)
clean the app (Product > Clean)
Run the app in a simulator (for this tutorial I will assume 4.2)
While the simulator is running, in a Finder window, navigate to:
{home} > Library > Application Support > iPhone Simulator > 4.2 > Applications > {random identifier} > Documents > {appname}.sqlite
Copy this file to another location
Stop running your app in X-Code
Drag and drop the {appname}.sqlite file into the files list in X-Code.
In the dialog that pops up, make sure the copy to folder checkbox, is checked.
Product > Clean
Then run the app in the simulator again
Now you should have a working sqlite file!
Cheers,
Robert
I noticed several questions related to this topic go unanswered. Is this such a gray area that nobody really understands it?
Here is my problem:
I am a midway in the development of my app and the app has never been used ouside of my iphone simulator.One of the attributes in my core data structure requires a type change.Since my app has never been used outside of my iPhone Simulator, I first deleted the sqlite file. Doubling the effort of this step, I also went into iPhone Simulator menu and selected "Reset Content and Settings...".
Than, I edited the xcdatamodel file and changed the type of my attribute. I saved the file and exited. Without any other changes, I compiled. I expected it to fail because of my type change. It did not! After this, I assigned a value with new type to my attribute and it fails to compile?!
Is there something else that I need to do for the change to take an effect?
I would really, really appreciate an answer to my question.
Thank you!
Core Data sometimes acts weird until you do Build -> Clean to build from scratch.
When you change the model and there is no sqlite file then Core Data will just create one off of the current model, so your first instance makes perfect sense.
In your second instance, if you did not delete the sqlite file (or reset the sim) between those two iterations you would get an error because the sqlite file already exists from the last run and it no longer matches the model.
Whenever you change the model you need to either version it or delete the sqlite file. Otherwise they will not match and produce an error.
If that is not the issue then it would be very helpful if you gave the details of the error you are seeing.
update
I'd still like to know the right way of dealing with the changes in core data in early development stages when there should not be a need for the migration.
The right way is to delete the application / reset the simulator and start with a fresh sqlite file. There is no other option other than migration and as you surmised, that is incorrect during development.
I'm trying create 2 apps, one that builds a persistent store, and another one that consumes it.
So far I have built one app that uses CoreData to successfully build a database from an XML file. So this project contains the data model, the .h/.m files for the entities, etc.
I'm now trying to enable the second app to read that .sqlite file by copying the data model file, the .h/.m files related to the entities and the sqlite file to that project (via add existing).
The code executes but always fails to find any objects in the database.
Are there any restrictions or correct steps to take when trying to copy over these files?
The solution here is deceptively simple.
Just copy your .xcdatamodel file from one project to another and then when you run your app in the simulator for the first time it'll create a Documents folder for the app. Just drop your saved .sqlite or .binary files into the yourApp/Documents directory on the device.
You can find the simulator directory in "~user/Library/Application Support/iPhone Simulator".
You can also download, edit, and upload the myApp directory on a provisioned iPhone by dragging and dropping into and out of the Organizer. Look at the Applications list.
The iPhone doesn't support xml stores with core data, only sqlite or atomic (binary). The sqlite store is by far the better option for most applications since it doesn't all have to be loaded into memory at runtime.
Is this what you meant?
I think (not 100 percent sure) in your app plist, if you set your application bundle name to the same thing, they will share resources because the device will think they are the same application...
I don't think this is going to work the way that you want it to. On the iPhone, each application runs in its own "sandbox", and it's not really possible for one application to write files that another can read.
Is it really two different projects, or is it two targets in the same project? That would seem to make a lot more sense, and then you can share entity objects as they change.
For copying core data files from one project to another, I first created a new project with core data support and then I opened the contents of the previous coredata file and except the root tag, pasted all child tags in the new core data file in new project.
Previousy I tried to delete the coredata file in new project, copy pasted the previous one and changed its name and it was not working.
I've created an sqlite3 database from the command line and inserted several records. My app retrieves all of them and shows them just fine. I then go back and insert a few more records via the sqlite3 cli, erase the db file out of the simulator's documents directory so that it will be recopied from the main bundle, and the run the app again only to find that it only displays the original records I inserted. The new records do not show. I verified that the new db file was copied to the simulators documents directory, and when I point the sqlite3 cli at it, I can do a select * and see all the records.
What could be going on here? It almost seems as if the previous version of the db file is being cached somewhere and used instead of my updated version.
//Scott
every time you rebuild and run an app in xcode, it creates a new folder under the iphone simulator's applications folder. If your sqlite db is being included from xcode the old db could be put in the new folder while the one your editing is in the old and now unused folder.
I haven't verified his answer, but Stephan Burlot said:
Sqlite uses a cache for requests. Close & reopen the database from time to release cache memory.
(I don't think it's true that every SQLite instance caches requests, but that might be the case on the iPhone.)
Obviously you aren't concerned with memory, but if it is caching requests, maybe just a close and reopen is all you need.
If that isn't the case, my next guess would be that your app is not pointing to the file you think it is pointing to -- did you have it pointing to a database with a different name at one point and forget to update the app? You could verify this by updating the db from within your app, then checking for those updates with the CLI. You might just find that they are not looking at the same db.