2013-12-26 3 views
2

Мое приложение синхронизирует и резервирует свои данные через iCloud (для этого я использую iCloudCoreDataStack). Поскольку мое приложение обрабатывает важные данные, созданные пользователем, я хочу предложить дополнительную защиту от возможности создавать моментальные снимки время от времени, которые могут быть восстановлены позже.Снимки данных в приложении Core Data, поддерживаемом iCloud?

Я не говорю об отмене одного или двух отдельных изменений, но о реальных моментальных снимках, timestamped и сохраненных в порядке сохранения.

Поскольку я использую синхронизацию iCloud, я не могу просто обменять хранилище sqlite, используемое в приложении. Я думаю, что мне нужно удалить каждый объект в текущем контексте, создать объекты, восстановленные из моментального снимка, и сохранить контекст. Затем устройство также будет изменять изменения в iCloud.

Я имею в виду следующий сценарий: нормальный

  1. Приложение работает без опции для создания моментальных снимков (это просто дополнительная функция безопасности для пользователя).
  2. Если пользователь отказывается создавать моментальные снимки время от времени, он просит ввести свои учетные данные для входа в Dropbox (уже реализовано).
  3. Время от времени мое приложение создает фоновый поток, в котором будет установлено второе хранилище и второй MOC (и второй PSC?). Каждый объект вместе со своими отношениями копируется в этот второй MOC. Второй MOC будет сохранен, постоянный магазин будет скопирован в Dropbox, и поток завершится.
  4. Если пользователь хочет восстановить снимок и отбросить все изменения, сделанные после создания снимка, мое приложение будет восстановить данные, делая обратно то, что описано в пункте 3.

Любые мысли о том, что? Сохраняется ли это, есть ли какие-либо оговорки, о которых можно подумать (например, вместе с iCloud)? Кто-нибудь сделал это еще подобным образом?


Edit:

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

Однако я столкнулся Яблоки «Сохранить как ...» или метод «Смена места жительства»

NSDictionary *options = @{ 
    NSPersistentStoreRemoveUbiquitousMetadataOption: @YES 
}; 
NSPersistentStore *copy = [psc migratePersistentStore:currentiCloudStore 
               toURL:url 
               options:options 
              withType:NSSQLiteStoreType 
               error:&error]; 

, который удалит все ICloud соответствующие метаданные, а также удаляет текущий магазин из координатор (я этого не хочу) и добавляет вновь созданный магазин в PSC (я тоже этого не хочу).

Что может быть лучше? Мой нынешний подход или Яблоки, встроенные в "Сохранить как .../Переместить"? Мое внимание сосредоточено на загрузке снимков позже, независимо от того, был ли включен iCloud или нет.

ответ

1

Ваш базовый подход выглядит хорошо для меня. Я также использую iCloudCoreDataStack, который, по моему мнению, является надежным решением.

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

Если вы уже выполняете итерацию по графу объектов, вы можете использовать это, чтобы сделать что-то дополнительное, что может оказаться полезным. Вы можете преобразовать весь граф объекта в JSON и сохранить его в виде текстового файла (если нет трансформируемых или двоичных атрибутов). Ваши данные теперь доступны для чтения и использования человеком многими другими способами и многими другими платформами.

+0

Спасибо, я был в состоянии сделать это. Любые мысли по моему правлению относительно сборки Apple в методе «Переместить»? – Norbert

0

В настоящее время я разрешаю пользователю использовать опцию File Save As для создания резервной копии любых файлов основных данных в OS X, и это использует интерфейс migratePersistentStore для создания новой копии без параметров iCloud. Конечно, это не обязательно, если файл еще не сохранен в iCloud, пользователь может просто скопировать файл с помощью диспетчера файлов. На устройствах iOS вы должны использовать один и тот же подход, за исключением того, что вам нужно написать собственный файловый менеджер, чтобы скопировать любые файлы, поэтому, возможно, проще просто использовать API migratePersistentStore для создания нового файла. Чтобы восстановить файл, вам необходимо перенести его в iCloud, вы не можете просто скопировать его обратно. Взгляните на эту ссылку, где я разместил несколько объяснений и пример кода, а также некоторые видео, показывающие, как файлы перемещаются в iCloud и из него, когда использование изменяет их настройки предпочтений iCloud. Это приложение, основанное на документе, позволяет создавать несколько документов, было бы тривиально просто добавить всплывающее меню в FileListViewController для создания файла резервной копии в выбранном вами месте.

http://ossh.com.au/design-and-technology/software-development/uimanageddocument-icloud-integration/

1

Я также искал решение, чтобы позволить своим пользователям выполнять резервное копирование снимка. Я не мог использовать migratePersistentStore, потому что он удалил мой активный магазин в этом процессе. Затем я подумал, могу ли я добавить магазин в РАЗЛИЧНЫЙ PSC, а затем перенести его, тем самым оставив исходный PSC нетронутым. Этот код для резервного копирования, похоже, работает, не прерывая мой текущий стек. Я немного не уверен в добавлении магазина в 2 PSC.

- (void)backupStore {//saves the store to backup.sqlite 

    NSFileManager *fm = [[NSFileManager alloc] init]; 
    NSError *localError = nil; 
    _ubiquityURL = [fm URLForUbiquityContainerIdentifier:nil]; 
    NSURL *backupStoreURL = [NSURL fileURLWithPath:[[self applicationDocumentsDirectory] stringByAppendingPathComponent: @"backupStore.sqlite"]]; 
    NSURL *iCloudStoreURL = [self iCloudStoreURL]; 
    NSMutableDictionary *options = [NSMutableDictionary dictionaryWithObjectsAndKeys: 
           [NSNumber numberWithBool:YES],  NSMigratePersistentStoresAutomaticallyOption, 
           [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, 
           nil]; 
    [options setObject:@"Logbook" forKey:NSPersistentStoreUbiquitousContentNameKey]; 
//Add the store to tempPSC 
    NSPersistentStoreCoordinator *tempPSC = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[NSManagedObjectModel mergedModelFromBundles:nil]]; 
    NSPersistentStore *store = [tempPSC addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:iCloudStoreURL options:options error:&localError]; 
    //migrate the store to local database 
    options = [NSMutableDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES], NSPersistentStoreRemoveUbiquitousMetadataOption,nil]; 
    if ([tempPSC migratePersistentStore:store toURL:backupStoreURL options:options withType:NSSQLiteStoreType error:&localError]) { 
     NSLog(@"migratePersistentStore did it!!"); 
    } else { 
     NSLog(@"migratePersistentStore failed!!...%@",localError); 
    } 

} 
+0

Спасибо, что подошли. Я попросил TSI в Apple и дал вам знать, что они говорят, когда я получаю от них ответ. – Norbert

+0

Был ли ответ TSI утверждать, что это нормально включить в приложение для доставки? – Conor

1

В создании хранилища резервных копий, следует помнить, что есть сообщения, что migratePersistentStore будет Nuke все много-ко-многим без каких-либо ошибок или признак того, что он делает это. У меня есть функция резервного копирования в моем приложении (с аналогичным для обмена через Bonjour) с помощью migratePersistentStore и начала получать некоторые отчеты пользователей о недостающих данных. Хотя вышеупомянутые решения будут работать, вы можете спокойно потерять данные. Или, если у вас нет отношения «многие ко многим» в вашей схеме, вы, надеюсь, будете в порядке. Не отличное чувство для функции «резервного копирования», верно?

Я боролся с этим в течение нескольких дней, пока не нашел сообщение Ивана Павлова в https://devforums.apple.com/message/1055235#1055235, где он подал на него радар 18480943.

Подводя итог, я бы не использовал migratePersistentStore, если ваша схема имеет отношения «многие-ко-многим», если вы не вернетесь назад и не вручную воссоздаете все ссылки в этих отношениях после миграции.

+0

Любая идея, почему это может произойти с технической точки зрения? – Norbert

Смежные вопросы