Почему отношения "многие ко многим" исчезают при перемещении основного хранилища данных?

У меня есть приложение, которое использует Core Data для сохранения информации. Я добавляю расширение Share в свое приложение, которому потребуется доступ к тем же данным, поэтому мне нужно переместить мое постоянное хранилище из изолированной программной среды моего приложения в изолированную программную среду группы приложений. Как рекомендовано в разделе "Обновление хранилища основных данных для поддержки групп приложений", для этого я использую миграцию. Проблема в том, что мои отношения многие ко многим исчезают во время этой миграции.

Мне удалось воссоздать проблему, начав с базового приложения Single View с базовыми данными. Кнопка подключена, чтобы создать объекты в defaultObjectContext по умолчанию (к которому мне пришлось добавить очередь), и показать сообщение о состоянии:

AppDelegate * delegate = [UIApplication sharedApplication].delegate;

[delegate.managedObjectContext performBlock:^{
    Book * book1 = [[Book alloc] initWithEntity:[NSEntityDescription entityForName:@"Book" inManagedObjectContext:delegate.managedObjectContext] insertIntoManagedObjectContext:delegate.managedObjectContext];

    Book * book2 = [[Book alloc] initWithEntity:[NSEntityDescription entityForName:@"Book" inManagedObjectContext:delegate.managedObjectContext] insertIntoManagedObjectContext:delegate.managedObjectContext];

    Topic * topic1 = [[Topic alloc] initWithEntity:[NSEntityDescription entityForName:@"Topic" inManagedObjectContext:delegate.managedObjectContext] insertIntoManagedObjectContext:delegate.managedObjectContext];

    Topic * topic2 = [[Topic alloc] initWithEntity:[NSEntityDescription entityForName:@"Topic" inManagedObjectContext:delegate.managedObjectContext] insertIntoManagedObjectContext:delegate.managedObjectContext];

    Topic * topic3 = [[Topic alloc] initWithEntity:[NSEntityDescription entityForName:@"Topic" inManagedObjectContext:delegate.managedObjectContext] insertIntoManagedObjectContext:delegate.managedObjectContext];

    book1.title = @"Breadbaker's Apprentice";
    book1.authorName = @"Peter Reinhart";

    book2.title = @"Tartine Bread";
    book2.authorName = @"Chad Robertson";

    topic1.topicName = @"Bread";
    topic1.topicPriority = [NSDecimalNumber decimalNumberWithString:@"0.9"];
    [topic1 addBooksObject:book2];

    topic2.topicName = @"Baking";
    topic2.topicPriority = [NSDecimalNumber decimalNumberWithString:@"0.7"];
    [topic2 addBooksObject:book1];
    [topic2 addBooksObject:book2];

    topic3.topicName = @"San Francisco";
    topic3.topicPriority = [NSDecimalNumber decimalNumberWithString:@"0.2"];
    [topic3 addBooksObject:book2];

    NSError * saveError;
    if(![delegate.managedObjectContext save:&saveError])
    {
        NSLog(@"Failed to save for some reason: %@", saveError.debugDescription);
        dispatch_async(dispatch_get_main_queue(), ^{
            self.statusLabel.text = [NSString stringWithFormat:@"Failed to save for some reason: %@", saveError.debugDescription];
        });
    }
    else
    {
        dispatch_async(dispatch_get_main_queue(), ^{
            self.statusLabel.text = @"OK, added objects";
        });
    }

}];

При запуске в симуляторе я могу использовать sqlite3 в командной строке для проверки базы данных SQLite и, в частности, таблицы ссылок Z_1TOPICS, которую создает Core Data, после добавления этих объектов:

sqlite> .tables
ZBOOKS        ZTOPICS       Z_1TOPICS     Z_METADATA    Z_PRIMARYKEY
sqlite> SELECT * from Z_1TOPICS;
1|3
1|2
2|2
2|3
2|1

Все выглядит правильно. Затем настраивается вторая кнопка для переноса постоянного хранилища в каталог группы приложений:

AppDelegate * delegate = [UIApplication sharedApplication].delegate;

NSURL *newStoreURL = [[delegate groupDocumentsDirectory] URLByAppendingPathComponent:@"Migration_Bug_Demonstration.sqlite"];

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

NSManagedObjectModel * managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];

NSPersistentStoreCoordinator *tempCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel: managedObjectModel];

NSURL *oldStoreURL = [[delegate applicationDocumentsDirectory] URLByAppendingPathComponent:@"Migration_Bug_Demonstration.sqlite"];

NSPersistentStore   *sourceStore        = nil;
NSPersistentStore   *destinationStore   = nil;
NSDictionary *RWoptions = @{NSMigratePersistentStoresAutomaticallyOption: @YES,
                            NSInferMappingModelAutomaticallyOption: @YES};
NSDictionary * ROoptions = @{NSReadOnlyPersistentStoreOption:@YES,NSMigratePersistentStoresAutomaticallyOption: @YES,
                             NSInferMappingModelAutomaticallyOption: @YES};
NSError * error;
// Add the source store
if (![tempCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:oldStoreURL options:ROoptions error:&error]){
    // Handle the error
    NSLog(@"Error adding old store: %@ -- %@", error, error.userInfo);
}
else
{
    sourceStore = [tempCoordinator persistentStoreForURL:oldStoreURL];
    if (sourceStore != nil){
        // Perform the migration
        destinationStore = [tempCoordinator migratePersistentStore:sourceStore toURL:newStoreURL options:RWoptions withType:NSSQLiteStoreType error:&error];
        if (destinationStore == nil){
            NSLog(@"Error migrating store: %@ -- %@", error, error.userInfo);
            // Handle the migration error
            dispatch_async(dispatch_get_main_queue(), ^{
                self.statusLabel.text = [NSString stringWithFormat:@"Failed to migrate: %@", error.debugDescription];
            });
        } else {

            dispatch_async(dispatch_get_main_queue(), ^{
                self.statusLabel.text = @"OK, moved store";
            });
        }
    }
}

Большая часть этого кода прямо из Вопроса, указанного выше. Отношения между Книгами и Темами не переносятся, но сами объекты:

sqlite> .tables
ZBOOKS        ZTOPICS       Z_1TOPICS     Z_METADATA    Z_PRIMARYKEY
sqlite> SELECT * FROM Z_1TOPICS;
sqlite> SELECT * FROM ZTOPICS;
1|2|1|0.2|San Francisco
2|2|1|0.7|Baking
3|2|1|0.9|Bread
sqlite> SELECT * FROM ZBOOKS;
1|1|1|Peter Reinhart|Breadbaker's Apprentice
2|1|1|Chad Robertson|Tartine Bread

Действительно, используя аргумент запуска "-com.apple.CoreData.SQLDebug 1" перед выполнением всего этого, я могу убедиться, что Core Data записывает в таблицы ZTOPICS и ZBOOKS, но никогда в таблицу Z_1TOPICS.

Так что теперь я застрял. Я даже не уверен, что еще я могу сделать, чтобы исследовать эту проблему - может быть, выполнить пользовательскую миграцию, чтобы я мог наблюдать (или даже вручную выполнять) миграцию отношений? Я мог бы просто попытаться переместить файлы постоянного хранилища вручную (даже если это Нет-Нет), потому что я не уверен, что еще я могу сделать. Спасибо за ваше время.

0 ответов

Другие вопросы по тегам