IOS - Managing Two CoreData Models Using MagicalRecord

I use MagicalRecord to work with the CoreData model, which is likely to be versioned in the future.

Now I need to add to my application a pre-populated database with about 80,000 objects with one entity; this data is static, and I do not expect it to ever change.

If I added this entity to an existing model, I would need to generate a new seed db every time the model changes, increasing the complexity of the project.

The best solution would be to create a second model, only for a new object: the seed db will never change, and the first model can take care of its version, regardless of the new model. No relationship between the two models is required.

In addition to the existing model, I also use RestKit, and here, as everything is configured:

[MagicalRecord setupAutoMigratingCoreDataStack];
RKManagedObjectStore *managedObjectStore =
    [[RKManagedObjectStore alloc] initWithPersistentStoreCoordinator:
        [NSPersistentStoreCoordinator MR_newPersistentStoreCoordinator]];
self.objectManager.managedObjectStore = managedObjectStore;
[managedObjectStore createManagedObjectContexts];
// bind RK with MagicalRecord
[NSManagedObjectContext MR_setRootSavingContext:
    managedObjectStore.persistentStoreManagedObjectContext];
[NSManagedObjectContext MR_setDefaultContext:
    managedObjectStore.mainQueueManagedObjectContext];
managedObjectStore.managedObjectCache = [[RKFetchRequestManagedObjectCache alloc] init];

The new model will not be used with RestKit.

Is this possible with MagicalRecord? I went through his documentation, but could find something useful.

Thanks a lot, DAN

UPDATE

db 4 (Foo, Bar, Blarg, Baz), xcode. , , (SeedConfiguration UserConfiguration), Foo , - . seed.sqlite user.sqlite. script, seed.sqlite Foo: ; user.sqlite .

"script" seed.sqlite, sqlite , , Foo seed.sqlite Bar, Blarg, Baz user.sqlite.

Foo seed.sqlite, () ?

: qaru.site/questions/531130/...

, sqlite, , db , .

0
1

, MagicalRecord, , .

, , , - . .

Apple , .

OK DAN, ( ) . / , , , .

, , ( ), , .

, , , .

, .

- (NSManagedObjectModel *)makeConfigurationModel {
    NSAttributeDescription *nameAttr = [[NSAttributeDescription alloc] init];
    nameAttr.name = @"name";
    nameAttr.attributeType = NSStringAttributeType;

    NSEntityDescription *foo = [[NSEntityDescription alloc] init];
    foo.name = @"Foo";
    foo.properties = @[[nameAttr copy]];
    NSEntityDescription *bar = [[NSEntityDescription alloc] init];
    bar.name = @"Bar";
    bar.properties = @[[nameAttr copy]];

    NSEntityDescription *blarg = [[NSEntityDescription alloc] init];
    blarg.name = @"Blarg";
    blarg.properties = @[[nameAttr copy]];
    NSEntityDescription *baz = [[NSEntityDescription alloc] init];
    baz.name = @"Baz";
    baz.properties = @[[nameAttr copy]];


    NSManagedObjectModel *model = [[NSManagedObjectModel alloc] init];
    model.entities = @[foo, bar, blarg, baz];
    [model setEntities:@[foo, bar] forConfiguration:@"One"];
    [model setEntities:@[blarg, baz] forConfiguration:@"Two"];

    return model;
}

, PSC -. , .

- (void)setupDatabaseWithModel:(NSManagedObjectModel*)model
                        store1:(NSURL*)store1URL
                        store2:(NSURL*)store2URL {
    @autoreleasepool {
        NSPersistentStoreCoordinator *psc = [[NSPersistentStoreCoordinator alloc]
            initWithManagedObjectModel:model];
        [psc addPersistentStoreWithType:NSSQLiteStoreType
                          configuration:@"One"
                                    URL:store1URL
                                options:nil
                                  error:NULL];
        [psc addPersistentStoreWithType:NSSQLiteStoreType
                          configuration:@"Two"
                                    URL:store2URL
                                options:nil
                                  error:NULL];
        NSManagedObjectContext *moc = [[NSManagedObjectContext alloc]
            initWithConcurrencyType:NSMainQueueConcurrencyType];
        moc.persistentStoreCoordinator = psc;

        // Add some entities...
        NSArray *entityNames = @[@"Foo", @"Bar", @"Blarg", @"Baz"];
        for (NSString *e in entityNames) {
            NSManagedObject *obj =
                [NSEntityDescription insertNewObjectForEntityForName:e
                                              inManagedObjectContext:moc];
            [obj setValue:[NSString stringWithFormat:@"%@ 1", e] forKey:@"name"];
        }
        [moc save:NULL];

        // Should have all of them in this MOC...
        for (NSString *e in entityNames) {
            NSFetchRequest *fetchRequest = [NSFetchRequest
                fetchRequestWithEntityName:e];
            NSArray *result = [moc executeFetchRequest:fetchRequest error:NULL];
            XCTAssertEqual(1, result.count);
            NSManagedObject *obj = [result firstObject];
            XCTAssertEqualObjects(([NSString stringWithFormat:@"%@ 1", e]),
                                  [obj valueForKey:@"name"]);
        }
    }
}

, ( ) .

- (void)checkStore:(NSURL*)storeURL
             model:(NSManagedObjectModel*)model
           present:(NSArray*)present
        notPresent:(NSArray*)notPresent {
    @autoreleasepool {
        NSPersistentStoreCoordinator *psc = [[NSPersistentStoreCoordinator alloc]
            initWithManagedObjectModel:model];
        [psc addPersistentStoreWithType:NSSQLiteStoreType
                          configuration:nil
                                    URL:storeURL
                                options:nil
                                  error:NULL];
        NSManagedObjectContext *moc = [[NSManagedObjectContext alloc]
            initWithConcurrencyType:NSMainQueueConcurrencyType];
        moc.persistentStoreCoordinator = psc;

        for (NSString *e in present) {
            NSFetchRequest *fetchRequest = [NSFetchRequest
                fetchRequestWithEntityName:e];
            NSArray *result = [moc executeFetchRequest:fetchRequest error:NULL];
            XCTAssertEqual(1, result.count);
            NSManagedObject *obj = [result firstObject];
            XCTAssertEqualObjects(([NSString stringWithFormat:@"%@ 1", e]),
                                  [obj valueForKey:@"name"]);
        }
        for (NSString *e in notPresent) {
            NSFetchRequest *fetchRequest = [NSFetchRequest
                fetchRequestWithEntityName:e];
            NSArray *result = [moc executeFetchRequest:fetchRequest error:NULL];
            XCTAssertEqual(0, result.count);
        }
    }
}

URL

static void removeURL(NSURL ** url) {
    [[NSFileManager defaultManager] removeItemAtURL:*url error:NULL];
}

...

- (void)testConfigurations {
    __attribute__((cleanup(removeURL))) NSURL * __autoreleasing dirURL =
        [[[NSFileManager defaultManager] URLForDirectory:NSDocumentDirectory
                                                inDomain:NSUserDomainMask
                                       appropriateForURL:nil
                                                  create:YES
                                                    error:NULL]
            URLByAppendingPathComponent:[[NSUUID UUID] UUIDString]];
    [[NSFileManager defaultManager] createDirectoryAtURL:dirURL
                             withIntermediateDirectories:YES
                                              attributes:nil
                                                   error:NULL];

    NSManagedObjectModel *model = [self makeConfigurationModel];
    NSURL *store1URL = [dirURL URLByAppendingPathComponent:@"store1"];
    NSURL *store2URL = [dirURL URLByAppendingPathComponent:@"store2"];
    [self setupDatabaseWithModel:model store1:store1URL store2:store2URL];
    [self checkStore:store1URL
               model:model
             present:@[@"Foo", @"Bar"]
          notPresent:@[@"Blarg", @"Baz"]];
    [self checkStore:store2URL
               model:model
             present:@[@"Blarg", @"Baz"]
          notPresent:@[@"Foo", @"Bar"]];
}
+1

Source: https://habr.com/ru/post/1769840/


All Articles