Blamdarot
Blamdarot

Reputation: 3317

One Application with Two Databases

My iPhone app currently uses Core Data to save Growth Entries created by the user. I'm trying to add a .sqlite file to the app that stores average growth data so that I can use Core Plot to show the user how their growth compares to the average.

Note: The average data does not need to be writable.

After much searching of Stack Overflow and countless Googles, I have come to the conclusion that what I want to do is implement two PersistentStoreCoordinators: one for the user entered data (readwrite), and one for the average data (readonly). Is that the best course?

If so, I don't know where to start. Currently, my Core Data Stack methods are in my AppDelegate.m (where Xcode put them). It feels like I should move them into a better place if I'm going to add much to them, but I don't know where that better place might be. And besides that, I don't know where I should start trying to add the new persistent store.

Thanks for the help!

Edit for clarification: If my suggestion of creating two PersistentStores is the right route, how do I do that? If it's not the best route, what should I do?

Upvotes: 2

Views: 1958

Answers (3)

Blamdarot
Blamdarot

Reputation: 3317

I have solved my problem. Here is what I did:

  • create a data model for the second database
  • in the appDelegate method managedObjectModel:, add code to merge the two models (NSManagedObjectModel modelByMergingModels:)
  • in the appDelegate method didFinishingLaunchingWithOptions:, add code to determine if the database already exists. If it does not exist, generate the data.

NOTE: you do not need to create the database before generating the data. That will be done for you automatically when you create a new entity.

The only downside for me is that I haven't found a way to prevent overwriting the data in the "second" database. But I'm still looking for a solution to that.

Upvotes: 1

Wienke
Wienke

Reputation: 3733

Here are some starters:

If you plan on using different combinations of entities in different stores, you’ll need to add “configurations” to your MOM. See Core Data Programming Guide > Managed Object Models for info.

The normal place to keep the actual database is in the “application support directory,” which is in the User > Library > Application Support > NameOfYourApp. A string representing this path is what the automatically generated applicationSupportDirectory method returns. (Oops, you're asking about iOS. There, the applicationDocumentsDirectory method returns a path to the sandbox.)

The automatically generated persistentStoreCoordinator accessor is where the store is added. You could make different versions of it to add different stores, or you could add a property to the application delegate that you use to keep track of which store to work with. For example, instead of making a url to point to the default “storedata” file, you could do this:

NSURL *url = [NSURL fileURLWithPath: [applicationSupportDirectory stringByAppendingPathComponent: @“nameOfStoreToAdd.sqlite”]];

In the addPersistentStoreWithType call, you’ll want to use NSSQLiteStoreType, rather than the default NSXMLStoreType. (If you ever get an NSUnderlyingException = "File at path does not appear to be a SQLite database.”, this is the issue.) And if you’ve set up different configurations for the MOM, you’ll want to add a string to identify the configuration for this store. Later, you might look into how to set up an options dictionary for the options parameter.

The automatically generated managedObjectContext is what calls the persistentStoreCoordinator accessor. So, again, you’ll need different versions of this or some property that is consulted to govern how the storeCoordinator accessor is called.

When you want to switch databases, you first save the current context, set it and the storeCoordinator to nil, then call the context accessor in such a way as to retrieve the other store. (Or you could probably keep multiple contexts open at the same time. Just be sure to set up separate properties to hold them and their storeCoordinators.)

The application delegate is accessible from any part of your app, just by calling [[NSApplication sharedApplication] delegate], so it makes sense to leave this code there. If it gets too long, you could always break it out to a category.

I’m no expert, so some of this may be a bit wobbly, but once you get started, you’ll probably have a better idea where to look for more detailed help.

Upvotes: 1

Jonah
Jonah

Reputation: 17958

You'll need to setup your Persistent Store Coordinator to use multiple persistent stores. Take a look at defining Configurations for your object model to control which model objects are stored in which persistent store.

Upvotes: 0

Related Questions