2

I'm writing an IOS app where I ultimately would like to have two different data stores, one for static data provided by us, and one for dynamic user data.

I have not been able to find detailed instructions on this in Apple's documentation, but this: http://developer.apple.com/library/iOS/#documentation/Cocoa/Conceptual/CoreData/Articles/cdBasics.html has an image where two managedObjectContexts are used with a single Persistent Store Coordinator. On the other hand this answer here: Can Core Data handle my "system vs. user data" migration needs? states that "You can add both stores to the NSPersistentStoreCoordinator and access them both from one NSMAnagedObjectContext".

So I did simple little experiment, which did not go as planned.

I created a new Navigation based app (in Xcode 3) that uses Core Data for storage. (the one where you press the plus button and it adds a time stamp) I added another entity called Person to the datamodel. Person has one property, name, which is NSString. In "Configurations:" I created two configurations "database1" and "database2". The original Event entity belongs to database1, while the Person entity belongs to database2.

I changed the persistentStoreCoordinator in the apps delegate to read as follows:

- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {

if (persistentStoreCoordinator_ != nil) {
    return persistentStoreCoordinator_;
}
NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"firstDB.sqlite"];
NSURL *secondStoreURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"secondDB.sqlite"];

NSError *error = nil;
persistentStoreCoordinator_ = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
if (![persistentStoreCoordinator_ addPersistentStoreWithType:NSSQLiteStoreType configuration:@"database1" URL:storeURL options:nil error:&error]) {
    NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
    abort();
}   
NSError *error2 = nil;
if (![persistentStoreCoordinator_ addPersistentStoreWithType:NSSQLiteStoreType configuration:@"database2" URL:secondStoreURL options:nil error:&error2]) {
    NSLog(@"Unresolved error %@, %@", error2, [error2 userInfo]);
    abort();
} 
return persistentStoreCoordinator_;
}

So I create two databases, one for each configuration in the datamodel.

When I run the app using the simulator, and look into the sql databases created I notice that while the timestamps are written to the correct database (firstDB.sqlite in the example above) both database include both a zEvent column and a zPerson column.

I see from here: Using two different Core Data Models in the same iPhone app. How can I do it? that I could also set up separate entire core stacks (which is the way I first thought about doing it) but I kind of like the idea of the different configurations if I can use them for the job.

I would really appreciate if you guys could tell me what I'm doing wrong here. I would like firstDB.sqlite to only include entities belonging to database1 configuration, and secondDB.sqlite to only include entities belonging to database2 configuration.

Community
  • 1
  • 1

1 Answers1

0

Looking at the sqlite files directly tells you next to nothing about how Core Data is structuring things. Core Data is an object graph manager. It just translates the object graph to sql using undocumented means. You can't assume that Core Data will create an sqlite file with any particular format/schema or that the format will be consistent from API version to API version.

I've never bothered to look at the sqlite stores for multi stores so I don't know whether they create empty tables for entities in other stores or not. It's not particularly relevant to how Core Data functions. I imagine that stores are structured based on the data model used to create them whether any particular entity is assigned to a particular store or not.

Don't make the mistake of thinking that Core Data is just a lightweight wrapper around SQL and that therefore you can figure out what is going on by looking at the SQL. SQL is just an option for Core Data, one that was tacked on late in the game.

TechZen
  • 64,370
  • 15
  • 118
  • 145
  • Thank you TechZen for your answer. I've been thinking quite a bit about this and I finally decided to go with two separate core data stacks, since I don't want any changes to the static data model to affect the dynamic data. I do realize Core Data is not just a lightweight wrapper around SQL, but I thought I could perhaps understand better how this works by looking at the databases. I was probably wrong. – HaukurPalma Sep 22 '11 at 20:27