Существующая базовая база данных не загружается в iCloud при включении iCloud в моем приложении

У меня есть простое приложение в App Store, которое является UITableView который заполняется пользователем, заполняющим некоторые UITextFieldв представлении, которое вызывается модально. Пользователь нажимает сохранить, и все идет сохранено в Core Data и используя NSFetchedResultsControllers, UITableView обновляется.

Я сейчас обновляю свое приложение, чтобы представить iCloud синхронизация (и версия для iPad).

Я новичок в iCloud разработка и хотя пост, за которым я следил http://goddess-gate.com/dc2/index.php/post/452 несколько лет назад, он в основном работает для меня.

проблема

Не вдаваясь в другие вопросы, единственной проблемой, с которой я сталкиваюсь сейчас, является тот факт, что, если я запускаю версию моего приложения в App Store с некоторыми данными (для которых не включен iCloud), когда я обновляю свое приложение используя мою разработку в Xcode, я ожидаю, что мои исходные данные все еще будут там и, следовательно, будут загружены в iCloud.

У меня нет флажка в моем приложении, говорящего не загружать, но я доберусь до этого. Пока проблема в том, что я начинаю с полностью пустой базы данных, когда обновляю свое приложение, хотя я подозреваю, что это просто проблема с моим кодом, который фактически отображает данные сейчас, потому что в настройках моего устройства он показывает 9,7 КБ данных хранится в iCloud (перед выполнением этого теста я удалил данные резервной копии iCloud).

Я изменил свой Идентификатор приложения на портале для разработчиков, чтобы включить iCloud, и откорректировал XCode, чтобы включить его, создавая новый сертификат SSL в Developer и добавив новые профили обеспечения в XCode.

Обновление: внесено много изменений в мое приложение и удален старый код

Вот мой App DelegatepersistentStoreCoordinator код: (следуя совету из ответа Тома)

- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
    if (_persistentStoreCoordinator != nil) {
        return _persistentStoreCoordinator;
    }

    NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"Planner.sqlite"];
    NSError *error = nil;
    _persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
    NSDictionary *options = @{
                              NSMigratePersistentStoresAutomaticallyOption : @YES,
                              NSInferMappingModelAutomaticallyOption : @YES
                              };
    if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:options error:&error]) {

        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        abort();
    }

    NSPersistentStore *ps = [_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:options error:&error];

    NSFileManager *fm = [NSFileManager defaultManager];
    NSURL *url = [fm URLForUbiquityContainerIdentifier:nil];
    NSDictionary *iCloudOptions = @{
                              NSMigratePersistentStoresAutomaticallyOption : @YES,
                              NSInferMappingModelAutomaticallyOption : @YES,
                              NSPersistentStoreUbiquitousContentNameKey : @"EnvysStore"
                              };
    NSPersistentStore *store = [[_persistentStoreCoordinator persistentStores] firstObject];

    store = [_persistentStoreCoordinator migratePersistentStore:ps toURL:url options:iCloudOptions withType:NSSQLiteStoreType error:&error];

    return _persistentStoreCoordinator;
}

Однако после запуска моего приложения оно вылетает с:

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'nil is not a valid persistent store' on the 

    store = [_persistentStoreCoordinator migratePersistentStore:ps toURL:url options:iCloudOptions withType:NSSQLiteStoreType error:&error];

проблема

Таким образом, проблема в том, что когда у меня есть версия моего приложения в App Store с некоторыми данными, а затем выполняется обновление до этой версии, сначала происходит сбой приложения, как описано выше, но как только я это исправлю, я хочу, чтобы мои существующие данные были перенесены в облако,

Любое руководство по этому вопросу будет высоко ценится!

1 ответ

Решение

Не вдаваясь в другие вопросы, единственной проблемой, с которой я сталкиваюсь сейчас, является тот факт, что, если я запускаю версию моего приложения в App Store с некоторыми данными (для которых не включен iCloud), когда я обновляю свое приложение используя мою разработку в Xcode, я ожидаю, что мои исходные данные все еще будут там и, следовательно, будут загружены в iCloud.

Это не так просто. Интеграция Core Data с iCloud использует журналы транзакций для синхронизации изменений. Журналы транзакций создаются каждый раз, когда вы сохраняете изменения в файле постоянного хранилища. Если вы просто добавите поддержку iCloud при наличии существующих данных, транзакции для этих данных не будут созданы. Нет журналов транзакций, нет синхронизации, и ваши данные остаются локальными.

Чтобы переместить существующие данные в iCloud, вам нужно перенести постоянное хранилище в новый файл в процессе генерации транзакций для всех существующих данных. Самый простой способ сделать это, позвонив [NSPersistentStoreCoordinator migratePersistentStore:toURL:options:withType:error:], который принимает те же параметры, что и при добавлении файла постоянного хранилища. Перенесите локальное хранилище в новое хранилище с поддержкой iCloud, и, если все будет работать, вы получите журналы транзакций и данные будут загружены.

Если ваши постоянные хранилища очень велики, вам может понадобиться использовать пользовательский код миграции. Тем не менее, в большинстве случаев встроенный метод миграции - это нормально.

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