Runtime-generated Custom NSManagedObjectModel for NSPersistentDocument

122 Views Asked by At

I have a document-based (OS X) app that uses Core Data, so the document is a subclass of NSPersistentDocument. When the user creates a document, s/he specifies a setting that determines the number of attributes a particular entity in the managed object model has. For example, a "Baseball Game" entity can have anywhere between 4 and 9 inning attributes, depending on how many the user specifies when creating the document. For efficiency purposes, the managed object models are generated at document creation with baseball game entities containing exactly the number of inning attributes specified. Therefore, a five inning document would have a different managed object model than a 9 inning document.

To set the managed object model dynamically, I have to override -(id)managedObjectModel in the document. This is trivial, and I can easily deliver a managed object model with the proper number of innings. However, if the user opens a saved document (with an unknown number of innings), I am again asked to give the document its managed object model through -(id)managedObjectModel. My conundrum is, how can I tell the document how many innings it has if I don't know myself? The managed object model is created and set at runtime, so the sensible thing to do is to stick some kind of property in the document that tells me how many innings there are. I was thinking of something similar to NSUserDefaults on a per-document basis, but no such thing exists. The only way I can think of is store store any entity/attribute that explicitly gives me the number of innings, but it wouldn't be accessible until I give the document its managed object model! What is the proper way to go about this?

1

There are 1 best solutions below

0
On

In fact you do have something like a per-document NSUserDefaults when you're using Core Data, because the persistent store file can save metadata about the file. That metadata can be whatever you want. Access the metadata via the persistent store coordinator. I haven't used NSPersistentDocument but if the URL isn't the same as the document URL, it looks like your subclass could do something like self.managedObjectContext.persistentStoreCoordinator.persistentStores to get at the correct location.

However I'm going to add that this sounds like the wrong approach to your problem. You have a game entity that relates to multiple inning instances. In nearly every case the right answer would be a to-many relationship from game to inning instead of multiple independent inning relationships. Give each inning an integer attribute called something like inningNumber so that you know which is which, and make your app logic limit the relationship to the range [4, 9]. Then you get all the space saving advantage you're looking for at far lower complexity. As a plus, if games ever have a different number of innings (extra innings?) you can keep on using the same data model.