ioscore-datasqlcipherencrypted-core-data-sql

Multiple data models with single persistent store coordinator


I inherited an iOS project that uses Core Data. This project has 8 different data models, no need to say that the project is not that big and that I can not see any good reason for splitting the entities over so many data models.

I am trying to use Encrypted Core Data with the current data models and persistent store coordinators and it is not working at all. Every data model is initialized like this:

    NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"First"
                                              withExtension:@"momd"];

    self.model = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
    
    // Coordinator
    //NSPersistentStoreCoordinator *psc = [EncryptedStore makeStore: self.model passcode: @"pass"];
    [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:self.model];

    NSURL *storeURL = [[[AppDelegate appDelegate] applicationDocumentsDirectory] URLByAppendingPathComponent: @"First.sqlite"];
    
    NSError *error = nil;
    [psc addPersistentStoreWithType:NSSQLiteStoreType
                              configuration:nil
                                        URL:storeURL
                                    options:nil
                                      error:&error];
    
    NSManagedObjectContextConcurrencyType ccType = NSMainQueueConcurrencyType;

    self.context = [[NSManagedObjectContext alloc] initWithConcurrencyType:ccType];
    [self.context setPersistentStoreCoordinator:psc];

So every data model has its own managed object model and its own persistent store coordinator with its persistent store and context.

What I see is that Encrypted Core Data (ECD) is only creating the tables in the firstly created persistent store. My suspicion is that ECD only handles the persistent stores added to a single coordinator. Based on that assumption I am wondering if it is possible to create a single coordinator and add several stores to it.

I am not that familiar with Core Data but I can't see how that would be possible since the coordinator is initialized with the managed object model (that points to a specific data model file containing only a set of the total number of entities in the project).

Any ideas? I really would like to avoid merging all the data models into a single one in order to use a single managed object model and coordinator (Actually I would like to do it but I am sure it would break everything and I don't really have to time for that right now).


Solution

  • You can't use a single persistent store coordinator without merging the models. However, you don't have to edit your data models-- you can merge them at run time. NSManagedObjectModel offers a couple of different ways to merge multiple models into a single unified model. If you load each model independently and merge them in code, you get a single NSManagedObjectModel representing the combined model from each model file. You could then use that combined model with a single persistent store coordinator.

    If you're still using multiple model files, you can add each one separately. This raises a complication though-- how will Core Data know which model file to use when you create a new model object instance? You would have to use the assignObject:toPersistentStore: method on NSManagedObjectContext to tell it which one to use. Every time you create a new instance, you do this as well. This means that you need to keep references to the NSPersistentStore instances for each file, and know which to use in every case.

    I should add that I have not used encrypted Core Data so I don't know if this will solve your real problem. This approach will allow multiple model files and multiple persistent stores with a single coordinator, though.