1

I created a new App using UIManagedDocument. While on my devices everything is fine, I got a lot of bad ratings, because there are problems on other devices :( After a lot of reading and testing, I decided to go back to the traditional Core Data stack. But what is the best way to do this with an app, that is already in the app store? How can I build this update? What should I take care of?

Thanks, Stefan

Urkman
  • 1,298
  • 1
  • 16
  • 32

2 Answers2

2

UIManagedDocument is a special kind of document, an UIDocument subclass, that stores its data using Core Data Framework. So it combines the power of document architecture and core data capabilities.

You can read more about document based architecture from Document Based App Programming Guide for iOS and I recommend WWDC2011 Storing Documents in iCloud using iOS5 session video. I also recommend Stanford CS193P: iPad and iPhone App Development (Fall 2011) Lecture 13.

What is created when you call saveToURL:forSaveOperation:completionHandler: is an implementation detail of UIManagedDocument and UIDocument and you should not really worry or depend on it. However in current implementation a folder containing an sqlite database file is being created.

No. All entities will be contained in a single database file also more generally called: a persistent store. It is possible to use more than one persistent store, but those are more advanced use cases and UIManagedDocument currently uses one.

UIManagedDocument's context refers to a NSManagedObjectContext from underlying Core Data Framework. UIManagedDocument actually operates two of those in parallel to spin off IO operations to a background thread. When it comes to the nature of a context itself here's a quote from Core Data Programming Guide:

You can think of a managed object context as an intelligent scratch pad. When you fetch objects from a persistent store, you bring temporary copies onto the scratch pad where they form an object graph (or a collection of object graphs). You can then modify those objects however you like. Unless you actually save those changes, however, the persistent store remains unaltered.

But it really is a good idea to take a look at the lectures and other material I posted above to get a general picture of the technologies used and their potential value to you as a developer in different situations.

prashant
  • 1,920
  • 14
  • 26
2

I think you may be better off to determine your issues with UIManagedDocument and resolve them.

However, if you want to go to plain MOC, you only have a few things to worry about. The biggest is that the UIMD stores things in a file package, and depending on your options you may have to worry about change logs.

In the end, if you want a single sqlite file, and you want to reduce the possibility of confusion, you have a class that simply opens your UIManagedDocument, and fetches each object, then replicates it in the single sqlite file for your new MOC.

Now, you should not need a different object model, so you should not have any migration issues.

Then, just delete the file package that holds the UIManagedDocument, and only use your single file sqlite store.

Basically, on startup, you try to open the UIManagedDocument. If it opens, load every object and copy it into the new database. Then delete it.

From then, you should be good to go.

Note, however, that you may now experience some UI delays because all the database IO is happening on the main UI thread. To work around this, you may need to use a separate MOC, and coordinate changes via the normal COreData notification mechanisms. There are tons of documents, examples, and tutorials on that.

EDIT

Thanks for your answer. My problem with these issues is, that I'm not able to reproduce them. All my Devices are working fine. But I got a lot mails, about problems like this: - duplicate entries - no data after stoping and restarting the app - some say, that the app works fine for some days and stops working(no new data). These are all strange things, that don't happen on my devices. So for me the best way is to go back to plain MOC. My DB doesn't hold many user generated data, all the data is loaded from a webservice, so it's no problem to delete the data and start of using a new DB. – Urkman

Duplicate entries. That one sounds like the bug related to temporary/permanent IDs. There are lots of posts about that. Here is one: Core Data could not fullfil fault for object after obtainPermanantIDs

Not saving. Sounds like you are not using the right API for UIManagedDocument. You need to make sure to not save the MOC directly, and either use an undo manager or call updateChangeCount: to notify UIManagedDocument that it has dirty data that you want to be saved. Again, lots of posts about that as well. Search for updateChangeCount.

However, you know your app best, and it may just be better and easier to use plain Core Data.

Remember, if you are doing lots of imports from the web, to use a separate MOC, and have your main MOC watch for DidSave notifications to update itself with the newly imported data.

Community
  • 1
  • 1
Jody Hagins
  • 27,943
  • 6
  • 58
  • 87
  • Thanks for your answer. My problem with these issues is, that I'm not able to reproduce them. All my Devices are working fine. But I got a lot mails, about problems like this: - duplicate entries - no data after stoping and restarting the app - some say, that the app works fine for some days and stops working(no new data). These are all strange things, that don't happen on my devices. So for me the best way is to go back to plain MOC. My DB doesn't hold many user generated data, all the data is loaded from a webservice, so it's no problem to delete the data and start of using a new DB. – Urkman Sep 04 '12 at 07:29
  • Hey there! I got your solution to work up to the point where I have created all object in the new database. However, the relationships are missing. Do you have any suggestion for this issue? – denrase Sep 03 '15 at 21:24