• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: Core Data Merged Models
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Core Data Merged Models


  • Subject: Re: Core Data Merged Models
  • From: Matthew Firlik <email@hidden>
  • Date: Sat, 22 Apr 2006 13:11:27 -0700


On Apr 22, 2006, at 2:13 AM, Jonathon Mah wrote:

The template code for a "Cocoa Core Data Application" creates a managed object model with the following code:

NSMutableSet *allBundles = [[NSMutableSet alloc] init];
[allBundles addObject:[NSBundle mainBundle]];
[allBundles addObjectsFromArray:[NSBundle allFrameworks]];

managedObjectModel = [[NSManagedObjectModel mergedModelFromBundles: [allBundles allObjects]] retain];

What is the purpose of merging models contained in frameworks? In other words, what advantage does this have over [[NSManagedObjectModel alloc] initWithURL:myMomURL] (apart from not needing to know the URL)?

The code is a small convenience to allow the template to work out-of- the-box (meaning, almost immediate turn-around) for those who are developing (just) an application or an application and framework (where the framework contains models as well.) The code to write to load a single model from its URL isn't complicated, though you do need to know the bundle it resides in (exploded here for clarity):


NSBundle *bundle = [NSBundle mainBundle]; /// or some other API ...
NSString *modelPath = [bundle pathForResource: @"MyModel" ofType:@"mom"];
NSURL *modelURL = [NSURL fileURLWithPath: modelPath];
NSManagedObjectModel *model = [[NSManagedObjectModel alloc] initWithContentsOfURL: modelURL]


Obviously if you have more than one model (and you plan to use them in concert), you need to have them merged before adding them to the coordinator. You can do that with the convenience API, or yourself using:

NSArray *models = [NSArray arrayWithObjects: model1, model2, /*(etc) */ nil];
NSManagedObjectModel *mergedModel = [NSManagedObjectModel modelByMergingModels: models];


Which isn't all that difficult, but since you have to locate the bundles for the models anyway to get the URL information, it's just as simple toss the bundles to the mergedModelsFromBundles: API and have it done for you. By the way, the code:

NSManagedObjectModel *model = [NSManagedObjectModel mergedModelFromBundles: nil];

defaults to loading all models from the main bundle ([NSBundle mainBundle]).



If the user added a framework to the system which contained its own MOM, could that render existing stores unreadable by apps using this code?

This is an important thing to think through. It can be dangerous to load models from all linked frameworks/bundles if you are unsure if they have models in them, or what the models actually contain. For example, in cases where separate developers haven't clearly (meaning, uniquely) named their entities, the merging API would complain about having conflicting entity descriptions when it went to merge. (Perhaps a little known fact, but Core Data will ignore an attempt to load the *exact same* entity more than once -- so if you tried to merge a model with itself, Core Data wouldn't be bothered.)


However, the true danger here is when using the SQL stores. When you create a SQL store with a model, Core Data will create tables for ALL entities in the specified model (even if you use a configuration, because the store must be able to support the model even if you change configurations to another collection of entities.) Thus, if you are (unaware that you are) loading models from frameworks, you'll have more tables in your store than you expected. That's not a problem in itself ... *unless* those models happen to change! If they did (including if the model goes away), then the merged model for your application would be different than before, and incompatible with any stores you created with the previous merge.

In summary -- the merged-models API is convenient and safe in situations where you own or are 100% certain of the content and stability of the bundles you are passing to it. For most developers, that probably means (just) passing their bundles or nil to get the correct resulting model. If you want to protect against accidentally loading other models, then the initWithContentsOfURL: method it your best bet. (As an aside, we've already changed the Xcode templates for the next major release to use the URL-based methods: as more frameworks add models, this will make loading more than one model a very conscious decision.)

Finally -- for all framework developers -- if you are worried about this case (where someone might accidentally load your model), or you are concerned about those who might explicitly load your model (because they see a resource with the .mom extension) to "troll" your data content without using your API, you might consider adding a shell- script build phase in Xcode to change the extension of your compiled model file to something other than ".mom." Doing so would mean the merged models API wouldn't "see" the model(s) (since it looks for resources with the ".mom" extension), thus making them accidental-load proof: it does mean any explicit consumers have to use the initWithContentsOfURL: method to load the model (or, go through API you provide), but it might be a good thing.

- matthew

_______________________________________________
Do not post admin requests to the list. They will be ignored.
Cocoa-dev mailing list      (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden


  • Follow-Ups:
    • Re: Core Data Merged Models
      • From: Matthew Firlik <email@hidden>
References: 
 >Core Data Merged Models (From: Jonathon Mah <email@hidden>)

  • Prev by Date: Re: Core Data Merged Models
  • Next by Date: CoreData questions (data sources and file wrappers)
  • Previous by thread: Re: Core Data Merged Models
  • Next by thread: Re: Core Data Merged Models
  • Index(es):
    • Date
    • Thread