Updating Iphone Application Content Using Core Data
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).
开发者_StackOverflow中文版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:
As for regenerating the core data persistent store ... how exactly are you accomplishing this? How do you know when to update the store or do you create the store every time the app runs?
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:
Does your app rebuild the sqlite db in the documents folder each time it runs as well?
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.
Honestly, I've been through all of this a hundred times over the past two years. I was never EVER satisfied with the way I had to hack and slash through core data ugliness whenever I wanted to update the contents of the database. Moreover, "seeding" the database prior to shipping the app was never as graceful or as obvious as it should have been.
All that has changed in the past week. I can say this with complete honesty, I have found the cure for all my anger and growing hatred of Core Data when it comes to keeping it up to date. I'm actually loving it now. Why? (for fear of sounding like an infomercial...)
I started using RestKit. It basically makes everything so much easier. I think it was originally intended to serve up objects to Core Data in realtime from JSON resources online, however, they've since added the ability to seed a database with JSON, with great ease.
Your JSON data online can be static text files (how I started out), or you can feed them out via a REST backend on a database, or whatever. RestKit doesn't provide this part for you, but there's lots of knowledgable folks on their forums in case you're uncomfortable with that.
Moreover, with only minor tweaking, I built my implementation of RestKit in my app to query the backend for only recent objects and load up the new data in-place in the background, while the app is running.
Seriously, seriously, seriously give this a look, particularly if you're just laying out a new app, since the implementation will go quicker. They've got some good examples to get you started.
There's a difference between updating content and modifying the data model. Updating content could be done within existing data model (schema). For example, your app might provide information about movies and periodically you could add or modify information for movies. This could be done by reading from a website and incorporating changes into the local Core Data store (which would serve as a local cache).
If, however, you anticipate changing the data model, then that's another matter. For example, you may have omitted movie length in your first release of the app. To add that, you will need to modify your data model. (Disclaimer: I don't know how easy it would be to programmatically modify a data model.)
Updating content should be relatively easy to design for. Modifying the data model would seem to be somewhat more complex - especially if modifications could not be handled by lightweight migration facilities.
When you talk about distributing content through the app store, you're really talking about updating the entire application. When you change out the database in your app, you'll have to rebuild the app, submit it, and wait a week for it to be approved. If you can find a way to publish just the database (or an XML file that can be parsed into the database) on a web server, you'll be able to update the content without changing the app itself. This will be much easier for non-technical folks maintaining the app, and also lets you get your updates out much more quickly.
What you need to do is develop a 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.
This is trivial because MacOS and iOS both use the same Core Data. As long as you develop the model on iOS and you don't use anything fancy e.g. storing a UIImage in a transformable attribute, then the same exact data model and store will work on both OSs.
Then you just need to use bindings to wire up the model to a simple GUI interface so that the users can update the store. Once they have the store file, they can just include it in the next build in the exact same place as the old store. The app will never know the difference.
If you want to push data out to existing installed apps, it becomes more complicated of course depending on exactly how you want to provide the new data.
精彩评论