I am in the process of creating my first iPhone app. The app currently uses core data with a sqlite database. The content stored in the database will stay static in the app, however down the road we may want to add more content to the app – this is where my issue is.
I know down the road I will not be in charge of maintaining the app, and those in charge may not be tech savvy – so I’d like to make it as easy as possible to update content. The more and more I read about updating using core data, the more it makes me think that it will be impossible to easily update the content. I’d also like to distribute updates via the app store (right now I am not allowed to store any data on a web server).
In my ideal setup, I’d like to be able to write a front-end (not on an iphone) for the database and have my users update the db content via a user-friendly GUI. Then simply take this updated db and push it out via the app store. Is this possible while still using core data? I’m reading about versioning and migration, and it all just seems really complex for my simple app (or have I mis-intrepreted this)? Would I be better off to just use a sqlite db without core data?
Anyways, I’m interested to hear any ideas on updating content with or with core data.
Thanks
I am currently doing exactly what you listed (minus the user friendly interface, mine is just a command line tool). It works great, I build and run the tool and it regenerates my core data persistent store sqlite database using a plist file. When you push out your app, files with the same filename will be overwritten. If your sqlite db for Core Data is called “asdf.sqlite” then you just make sure it is included with your new bundle and it will replace the older one.
HOWEVER, be careful about making changes to your data model. In this case you will need to perform data model migration and map the old model to the new one. If you try accessing a core data persistent store using an older data model, you will encounter run time errors.
If no one ever makes changes to the data model then you’re fine. Just use your custom tool for rebuilding the database and you can hand the project off to someone else.
Re:
My command line application has references (symlinks) to the same data models and entity source code as the iPhone app (this way changes in the iPhone project will be available to my command line tool). My project looks for a plist file and I had to custom program the app to run through the entire plist file and add that information to the core data database. Each time I run the application it will delete the old sqlite file and replace it with a new one. So if I needed to have someone else manage my application they would just need to know how to modify that plist file and how to run the command line application. Out pops a sqlite database in the debug folder where the application is built.
My application is a reference tool, so I only need to update my core data db when the reference material changes. When I do make changes, I copy the resulting sqlite file to my iPhone project and make sure it gets copied into the app bundle.
BTW, this approach only works if you plan on shipping READ ONLY data on your app. If the same persistent store will be written to when the deployed app is being used, then every time you update it the user’s changes will be lost. You can get around this by using multiple stores (one for read only and one for data written by the user).
The method I described assumes you are only making updates to the core data db through app store updates. If your core data generation code is inside your iphone app then you could regenerate the code everytime the app runs but it wouldn’t be needed if the data is static and not expected to change until you update the app.
RE:
Short Answer: No, my iPhone app does NOT rebuild the sqlite db each time it runs. My iPhone app NEVER rebuilds the db.
Long Answer: To clarify once more, there are two applications. App1 is the iPhone app that uses the core data db, and App2 is the desktop app that generates the core data db. Originally, there was only App1, the iPhone app. Each time the iPhone app ran, it would regenerate the sqlite db from a plist (XML) file. Since my db is very large, it increased the load time of my app by a LOT. This was unacceptable, so I made it so that the iPhone app only generated the db when it could not find the db file (an indication that the app is being run for the first time). Then I realized that there was no need to make the app load extra long the first time, so I removed that code completely from my iPhone application and made a separate Mac OSX command line application, app2, to handle generating the sqlite db. This program, app2, only runs on my computer, so I have to take the generated sqlite file and manually place it in my iPhone app1 project. This rebuilt sqlite db file is only made available to the user when I submit an update to the App Store.