Используя Хранилище SQLite с iCloud

Интеграция iCloud базовых Данных комбинирует SQLite-тип персистентный доступ хранилища с хранением iCloud. Следуйте стратегии реализации в этой главе для создания устойчивого, высокоэффективного поддерживающего iCloud приложения. Используя эти инструкции и пример кода, Вы будете учиться как:

Включение Поддержки iCloud

Чтобы начать использовать iCloud в Вашем приложении, необходимо сначала включить поддержку iCloud приложения в облаке и в проекте. Это эффективно соединяет два. После включения поддержки iCloud можно начать использовать контейнер повсеместности приложения, тестовую среду приложения в облаке. Вы выполняете две задачи добавить iCloud к новому Базовому приложению Данных:

  1. Создайте приложение ID на портале разработчика.

    Создайте приложение ID на iOS Центр Dev в developer.apple.com. Приложения, использующие iCloud, не могут использовать подстановочные идентификаторы. Установите свой проект в элемент кода с помощью Приложения ID, который Вы просто создали.

  2. Включите iCloud в XCode.

    Перейдите к цели своего приложения в настройках проекта в XCode и выберите область возможностей. Щелкните по переключателю, следующему за iCloud, как показано на рисунке 1-1. XCode конфигурирует Ваше Приложение ID в портале разработчика и добавляет права на Ваше приложение. Эти права дают Ваше разрешение приложения получить доступ к его контейнеру (ам) повсеместности. По умолчанию XCode создает один идентификатор контейнера повсеместности с помощью Приложения ID.

    Рисунок 1-1  , Разрешающий возможность iCloud

Добавление поддерживающего iCloud Персистентного Хранилища к Базовым Данным

После включения iCloud приложение может начать сохранять документы и данные к контейнеру повсеместности. При создании Данных Ядра SQLite-типа, персистентное хранилище с включенной поддержкой iCloud, Базовые Данные использует контейнер повсеместности для сохранения объектов модели к iCloud. Поэтому необходимо создать поддерживающее iCloud персистентное хранилище, чтобы начать использовать iCloud. Посмотрите Мигрирующие Пользовательские Данные к iCloud для дополнительных задач, которые должны быть выполнены при включении iCloud в существующем Базовом приложении Данных.

Поскольку Вы были бы для типичного Базового приложения Данных, добавлять NSSQLiteStoreType введите хранилище своему персистентному координатору хранилища. Вы передаете следующую пару ключ/значение в словаре опций для включения iCloud.

NSURL *documentsDirectory = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
NSURL *storeURL = [documentsDirectory URLByAppendingPathComponent:@"CoreData.sqlite"];
NSError *error = nil;
NSPersistentStoreCoordinator *coordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:<# your managed object model #>];
NSDictionary *storeOptions =
    @{NSPersistentStoreUbiquitousContentNameKey: @"MyAppCloudStore"};
NSPersistentStore *store = [coordinator addPersistentStoreWithType:NSSQLiteStoreType
                                                     configuration:nil
                                                               URL:storeURL
                                                           options:storeOptions
                                                             error:&error];
NSURL *finaliCloudURL = [store URL];

Для описания дополнительных опций, которые могут быть указаны, посмотрите Ссылку класса NSPersistentStoreCoordinator.

Контрольная точка

В этой точке Ваше приложение может создать поддерживающие iCloud Базовые Данные персистентное хранилище. Вы включили iCloud в XCode, создали повсеместное довольное имя и добавили поддерживающее iCloud персистентное хранилище с тем именем к Вашему персистентному координатору хранилища.

Установка: Создайте Базовый Стек данных и добавьте персистентное хранилище с повсеместным довольным опция имени.

Тест: Выполните приложение на устройстве. Если Базовые Данные успешно создали и сконфигурированный поддерживающее iCloud персистентное хранилище, платформа регистрирует сообщение, содержащее “Используя локальное хранение: 1”, и, позже, другое сообщение, содержащее “Используя локальное хранение: 0”.

Реакция на События iCloud

когда изменения происходят с данными в контейнере повсеместности Вашего приложения или к доступности самого контейнера, iCloud уведомляет Базовую платформу Данных. После получения сообщений от iCloud Базовые Данные переводят эти универсальные изменения состояния в события, которые целесообразны в контексте Вашего Базового Стека данных и соответствующие применимым на практике шагам, которые Вы предпринимаете, чтобы усовершенствовать пользовательский интерфейс Вашего приложения. Базовые Данные говорят Ваше приложение об этих событиях с помощью уведомлений.

Перед реализацией ответов на события iCloud полезно помнить некоторые общие руководящие принципы.

Особенно важно протестировать поддерживающее iCloud приложение для iOS на существующем устройстве. Средство моделирования iOS точно не моделирует использование iCloud при реальных условиях. Для получения дополнительной информации о тестировании Вашего приложения и решении проблем, посмотрите Поиск и устранение неисправностей.

Базовые данные конфигурируют Ваше персистентное хранилище

Первый случай iCloud происходит после того, как Вы добавите поддерживающее iCloud персистентное хранилище к своему персистентному координатору хранилища. Базовые Данные возвращают Ваше персистентное хранилище из вызова метода и сразу отправляют NSPersistentStoreCoordinatorStoresDidChangeNotification уведомление, чтобы позволить Вашему приложению знать, что персистентное хранилище было сконфигурировано для использования. Пользовательский информационный словарь этого уведомления содержит создаваемый NSPersistentStore объект. На рисунке 1-2 Ваше приложение добавляет поддерживающее iCloud персистентное хранилище, заставляющее Базовые Данные отправлять уведомление и начинать контейнерную установку. В обработчике для уведомления персистентное хранилище также доступно в пользовательском информационном словаре уведомления.

Рисунок 1-2  , Добавляющий поддерживающее iCloud персистентное хранилище

Контрольная точка

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

Установка: добавьте NSLog оператор в Ваших хранилищах «обработчика уведомления действительно изменялся».

Тест: Полностью удалите свое приложение из Вашего устройства и затем щелкните по кнопке запуска в XCode, чтобы переустановить Ваше приложение и вновь открыть его. Если Базовые Данные успешно создали и сконфигурированный поддерживающее iCloud персистентное хранилище, платформа вызывает Ваш обработчик уведомления и Ваш NSLog оператор распечатает к консоли в XCode.

iCloud Выполняет Разовую Установку

Когда пользователь запускает Ваше поддерживающее iCloud приложение впервые, Базовые Данные и система сотрудничают для создания контейнера повсеместности приложения. Инициализация контейнера повсеместности является продолжительной работой, полагающейся на сетевое соединение со службой iCloud. Из-за этого Базовая платформа Данных предоставляет Вам временное локальное персистентное хранилище, которое Вы используете, в то время как работа выполняется в фоновом режиме. На последующих запусках приложения уже инициализируется контейнер повсеместности, и Базовые Данные связаны с поддерживающим iCloud персистентным хранилищем.

Реакция на разовую установку

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

Рисунок 1-3  Разовая установка

Как проиллюстрировано на рисунке 1-3, когда установка заканчивается, Базовые Данные отправляют NSPersistentStoreCoordinatorStoresWillChangeNotification уведомление. В Вашем обработчике уведомления Вы сбрасываете свой контекст управляемого объекта и отбрасываете любые ссылки на существующие управляемые объекты. Как только Ваш обработчик заканчивает выполняться, эти объекты больше не действительны. Необходимо также предотвратить любое взаимодействие с временным локальным хранилищем в то время как Базовые переходы Данных к поддерживающему iCloud хранилищу. Отключение Вашего пользовательского интерфейса является самым простым способом сделать это в управляемом UI приложении и в большинстве случаев невидимо для пользователя. Это вызвано тем, что время между уведомлением-изменения и уведомлением-изменения чрезвычайно коротко.

[[NSNotificationCenter defaultCenter]
    addObserverForName:NSPersistentStoreCoordinatorStoresWillChangeNotification
                object:self.managedObjectContext.persistentStoreCoordinator
                 queue:[NSOperationQueue mainQueue]
            usingBlock:^(NSNotification *note) {
                [self.managedObjectContext performBlock:^{
                    [self.managedObjectContext reset];
                }];
                // drop any managed object references
                // disable user interface with setEnabled: or an overlay
            }];

Базовые Данные заканчивают выгружать временное локальное хранилище с поддерживающим iCloud хранилищем и отправляют NSPersistentStoreCoordinatorStoresDidChangeNotification уведомление. Пользовательский информационный словарь уведомления содержит поддерживающее iCloud хранилище как объект, связанный с NSAddedPersistentStoresKey ключ. В обработчике этого уведомления Вы повторно включаете свой пользовательский интерфейс и перевыборку.

Контрольная точка

Когда разовая установка закончена, в этой точке Ваши обработчики уведомления отключают, включают, и обновляют Ваш пользовательский интерфейс. Вы зарегистрировались для NSPersistentStoreCoordinatorStoresWillChangeNotification уведомления, где Вы отключаете свой пользовательский интерфейс. Вы также зарегистрировались для NSPersistentStoreCoordinatorStoresDidChangeNotification уведомления, где Вы повторно включаете пользовательский интерфейс своего приложения и повторно выбираете Ваши данные.

Установка: На Вашем устройстве на iOS начните с включенного авиарежима. Если Вы создаете приложение Mac, отключаете каждый сетевой интерфейс вместо этого. Полностью удалите свое приложение из Вашего устройства также.

Тест: Выполните свое приложение и создайте несколько записей. Отключите авиарежим или повторно включите сетевой интерфейс и ожидайте Базовых Данных для печати “Используя локальное хранение: 0” к консоли в XCode. Базовые Данные вызывают Ваши обработчики уведомления, и Ваши записи исчезают. В следующем разделе Вы изучите, как сохранить изменения в памяти.

Сохранение изменений в памяти

Если Ваш контекст управляемого объекта имеет изменения, не посвятившие себя временному хранилищу, сохраните те изменения так, чтобы Базовые Данные переместили их на поддерживающее iCloud персистентное хранилище. Ваш обработчик уведомления ведет себя немного по-другому: вместо того, чтобы сразу сбрасывать Ваш контекст управляемого объекта, Вы проверяете на изменения в Вашем контексте управляемого объекта и вызываете save:. Иначе, Вы следуете за тем же процессом, как описано в предыдущем разделе, сбрасывая Ваш контекст и отключая Ваш пользовательский интерфейс.

Рисунок 1-4  Разовая установка с сохранением

После сохранения Вашего контекста управляемого объекта Базовые Данные отправляют другого NSPersistentStoreCoordinatorStoresWillChangeNotification уведомление. Базовые Данные продолжают отправлять это уведомление, пока Вы больше не вызываете save: на Вашем контексте управляемого объекта и вместо этого сбросе это. Этот цикл проиллюстрирован выше на рисунке 1-4 и реализован ниже.

[[NSNotificationCenter defaultCenter]
    addObserverForName:NSPersistentStoreCoordinatorStoresWillChangeNotification
                object:self.managedObjectContext.persistentStoreCoordinator
                 queue:[NSOperationQueue mainQueue]
            usingBlock:^(NSNotification *note) {
                // disable user interface with setEnabled: or an overlay
                [self.managedObjectContext performBlock:^{
                    if ([self.managedObjectContext hasChanges]) {
                        NSError *saveError;
                        if (![self.managedObjectContext save:&saveError]) {
                            NSLog(@"Save error: %@", saveError);
                        }
                    } else {
                        // drop any managed object references
                        [self.managedObjectContext reset];
                    }
                }];
            }];

Контрольная точка

Когда разовая установка закончена, обработчики уведомления Вашего приложения отключают, включают и обновляют Ваш пользовательский интерфейс. Вы зарегистрировались для NSPersistentStoreCoordinatorStoresWillChangeNotification и NSPersistentStoreCoordinatorStoresDidChangeNotification уведомления для обработки перехода между временным локальным хранилищем и поддерживающим iCloud персистентным хранилищем после первоначальной установки контейнера повсеместности заканчиваются.

Установка: Начните с авиарежима, включенного на Вашем устройстве на iOS или всех сетевых интерфейсах, отключенных на Вашем Mac. Полностью удалите свое приложение из Вашего устройства также.

Тест: Выполните свое приложение и создайте несколько записей. Отключите авиарежим или повторно включите сетевой интерфейс. Тогда ожидайте Базовых Данных для печати “Используя локальное хранение: 0” к консоли в XCode. Базовые Данные вызывают Ваши обработчики уведомления, и Ваши записи сохраняются после того, как Ваш обработчик уведомления выполняет новый запрос выборки.

Базовые Изменения Содержания Сообщений Данных от iCloud

В то время как Ваше приложение работает, базовые изменения импорта Данных сохранились к iCloud от других коллег после первоначальной установки и. Базовые Данные представляют это событие как показано на рисунке 1-5.

  Содержание рисунка 1-5 изменяет импорт

Когда контейнер повсеместности получает изменения от iCloud, Базовые Данные отправляют NSPersistentStoreDidImportUbiquitousContentChangesNotification уведомление. Это уведомление userInfo словарь структурирован так же к тому из NSManagedObjectContextDidSaveNotification уведомление за исключением этого это содержит NSManagedObjectID экземпляры, а не NSManagedObject экземпляры. Поэтому можно объединиться в изменениях от других коллег таким же образом, что Вы объединяете изменения от других контекстов управляемого объекта. Вызвать mergeChangesFromContextDidSaveNotification: на Вашем контексте управляемого объекта, передающем в объекте уведомления, отправляется Базовыми Данными.

[[NSNotificationCenter defaultCenter]
    addObserverForName:NSPersistentStoreDidImportUbiquitousContentChangesNotification
                object:self.managedObjectContext.persistentStoreCoordinator
                 queue:[NSOperationQueue mainQueue]
            usingBlock:^(NSNotification *note) {
                [self.managedObjectContext performBlock:^{
                    [self.managedObjectContext mergeChangesFromContextDidSaveNotification:note];
                }];
            }];

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

Контрольная точка

В этой контрольной точке обработчик уведомления изменения Вашего приложения объединяет изменения от других коллег в Ваш контекст управляемого объекта. Вы зарегистрировались для NSPersistentStoreDidImportUbiquitousContentChangesNotification уведомление, где Вы решаете который данные обновляющая стратегия использовать — слияние в памяти или перевыборка данных.

Установка: Установите свое приложение на двух устройствах.

Тест: Выполните свое приложение на обоих устройствах и создайте несколько отличных записей на каждом. Ожидайте Базовых Данных для печати “Используя локальное хранение: 0” к консоли в XCode. Уведомления об изменении контента обычно следуют вскоре после, и каждое устройство добавляет записи других.

Базовые данные помогают Вам с переходами учетной записи

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

Реакция для учета переходов

В то время как Ваше приложение работает, Базовые работы Данных с Вашим приложением для подготовки к событию, когда система сообщает Базовым Данным о переходе учетной записи. Рисунок 1-6 показывает временную шкалу события перехода учетной записи.

  Переход Учетной записи рисунка 1-6

Так же, как во время разовой установки, Базовые Данные отправляют NSPersistentStoreCoordinatorStoresWillChangeNotification уведомление, сообщая Вам, что переход учетной записи происходит. В дополнение к добавленным и удаленным персистентным хранилищам, уведомление userInfo словарь также содержит тип перехода. Тип перехода, связанный с NSPersistentStoreUbiquitousTransitionTypeKey ключ, NSNumber объект отобразился на ключ NSPersistentStoreUbiquitousTransitionType перечисление. Можно использовать эту информацию для обнаружения, почему происходит переход.

В Вашем обработчике уведомления Вы сбрасываете свой контекст управляемого объекта и отбрасываете любые ссылки на существующие управляемые объекты. Как только Ваш обработчик заканчивает выполняться, эти объекты больше не действительны. В то время как Базовые Данные заканчивают переходить, необходимо также предотвратить любое взаимодействие с поддерживающим iCloud хранилищем. В управляемом UI приложении, отключая Ваш пользовательский интерфейс самый простой способ сделать это. Когда текущая учетная запись iCloud удалена, Базовые Данные сохраняют Ваше хранилище к специфичному для учетной записи архиву. Если пользователь подписывается в ту же учетную запись снова в будущем, Базовые Данные разархивировали данные и продолжают загружать.

Сохранение изменений в памяти

Поскольку это вело себя в первоначальной установке, Базовые Данные дают Вашему приложению шанс сохранить данные, не сохраненные к тому времени, когда уведомление было отправлено. Снова, потому что iOS удаляет старые хранилища, связанные с учетными записями iCloud, которые больше не активны на устройстве, Ваши изменения никогда не могут сохраняться или отправляться в облако.

  Переход Учетной записи рисунка 1-7 с сохранением

В отличие от того, как это вело себя в разовой установке, Базовые Данные дают Вашему приложению только один шанс сохранить; это не отправит другого NSPersistentStoreCoordinatorStoresWillChangeNotification уведомление. Как проиллюстрировано на рисунке 1-7 выше, сохраняя Ваш контекст управляемого объекта не вызывает цикл.

Контрольная точка

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

Установка: Установите свое приложение на устройстве с включенным iCloud.

Тест: Выполните свое приложение на обоих устройствах и создайте несколько отличных записей. Ожидайте Базовых Данных для печати “Используя локальное хранение: 0” к консоли в XCode. Тогда измените учетные записи iCloud — данные Вашего приложения должны исчезнуть, и Ваше персистентное хранилище должно быть восстановлено с новыми данными учетной записи iCloud.

Исходные данные отбора

Если Ваше приложение упаковывается с предварительно созданной базой данных или если предыдущая версия Вашего приложения не сохранялась к iCloud, Ваш персистентный координатор хранилища может создать поддерживающее iCloud персистентное хранилище и переместить записи на единственном шаге. Для изучения, когда хранить отобранные данные в iCloud посмотрите Хранилище Только Существенные Данные в iCloud.

После создания Вашего персистентного координатора хранилища и добавления Вашего существующего персистентного хранилища, выполните те же шаги в Добавлении поддерживающего iCloud Персистентного Хранилища к Базовым Данным, заменив вызов к addPersistentStoreWithType:configuration:URL:options:error: с вызовом к migratePersistentStore:toURL:options:withType:error:. Передайте в своем существующем персистентном хранилище как первый параметр в методе. Миграция персистентного хранилища является синхронной задачей, в отличие от добавления поддерживающего iCloud персистентного хранилища. Вы диспетчеризируете миграцию на очередь фоновых задач и затем обновляете Ваш пользовательский интерфейс после того, как миграция будет завершена.

Наконец, отметьте отбор как полное использование хранение значения ключа iCloud так, чтобы другие коллеги не отбирали те же данные. Посмотрите Разработку для Данных Значения ключа в iCloud в Руководстве по проектированию iCloud для больше об использовании хранения значения ключа iCloud.

NSURL *documentsDirectory = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
NSURL *storeURL = [documentsDirectory URLByAppendingPathComponent:@"CoreData.sqlite"];
NSError *error = nil;
NSPersistentStoreCoordinator *coord = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:<# your managed object model #>];
NSUbiquitousKeyValueStore *kvStore = [NSUbiquitousKeyValueStore defaultStore];
if (![kvStore boolForKey:@"SEEDED_DATA"]) {
    NSURL *seedStoreURL = <# path to your seed store #>
    NSError *seedStoreError;
    NSDictionary *seedStoreOptions = @{NSReadOnlyPersistentStoreOption: @YES};
    NSPersistentStore *seedStore =
                  [coord addPersistentStoreWithType:<#seed store type#>
                                      configuration:nil
                                                URL:seedStoreURL
                                            options:seedStoreOptions
                                              error:&seedStoreError];
    NSDictionary *iCloudOptions =
        @{NSPersistentStoreUbiquitousContentNameKey: @"MyAppCloudStore"};
    NSOperationQueue *queue = [[NSOperationQueue alloc] init];
    [queue addOperationWithBlock:^{
        NSPersistentStore *iCloudStore =
            [coord migratePersistentStore:seedStore
                                    toURL:storeURL
                                  options:iCloudOptions
                                 withType:NSSQLiteStoreType
                                    error:&error];
        NSURL *finaliCloudURL = [iCloudStore URL];
 
        [kvStore setBool:YES forKey:@"SEEDED_DATA"];
        NSOperationQueue *mainQueue = [NSOperationQueue mainQueue];
        [mainQueue addOperationWithBlock:^{
            // Update your user interface
        }];
    });
} else {
    // Add persistent store normally
}

Обнаружение и удаление двойных записей

Когда пользователь взаимодействует с Вашим приложением на многократных устройствах, Ваше приложение может закончить тем, что имело два или больше из тех же управляемых объектов. Для решения этой проблемы следующие шаги объясняют, как обнаружить и удалить двойные объекты. Дедупликация является процессом нахождения и удаления этих копий. Существует несколько общих ситуаций, в которых Ваше приложение должно выполнить дедупликацию:

В каждой из этих ситуаций задачами, которые Вы выполняете, является то же:

  1. Выберите свойство или хеш многократных свойств для использования в качестве уникального идентификатора для каждой записи.

    NSString *uniquePropertyKey = <# property to use as a unique ID #>
    NSExpression *countExpression = [NSExpression expressionWithFormat:@"count:(%@)", uniquePropertyKey];
    NSExpressionDescription *countExpressionDescription = [[NSExpressionDescription alloc] init];
    [countExpressionDescription setName:@"count"];
    [countExpressionDescription setExpression:countExpression];
    [countExpressionDescription setExpressionResultType:NSInteger64AttributeType];
    NSManagedObjectContext *context = <# your managed object context #>
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"<# your entity #>" inManagedObjectContext:context];
    NSAttributeDescription *uniqueAttribute = [[entity attributesByName] objectForKey:uniquePropertyKey];
  2. Выберите число раз, каждое уникальное значение появляется в хранилище.

    Контекст возвращает массив словарей, каждый содержащий оценивающие уникальное значение и число раз появился в хранилище.

    NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"<# your entity #>"];
    [fetchRequest setPropertiesToFetch:@[uniqueAttribute, countExpression]];
    [fetchRequest setPropertiesToGroupBy:@[uniqueAttribute]];
    [fetchRequest setResultType:NSDictionaryResultType];
    NSArray *fetchedDictionaries = <# execute a fetch request against your store #>
  3. Отфильтруйте уникальные значения, не имеющие никаких копий.

    NSMutableArray *valuesWithDupes = [NSMutableArray array];
    for (NSDictionary *dict in fetchedDictionaries) {
        NSNumber *count = dict[@"count"];
        if ([count integerValue] > 1) {
            [valuesWithDupes addObject:dict[@"<# property used as the unique ID #>"]];
        }
    }
  4. Используйте предикат для выборки всех записей с копиями.

    Используйте дескриптор вида для надлежащего упорядочивания результатов для алгоритма победителя на следующем шаге.

    NSFetchRequest *dupeFetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"<# your entity #>"];
    [dupeFetchRequest setIncludesPendingChanges:NO];
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"<# property used as the unique ID #> IN (%@)", valuesWithDupes];
    [dupeFetchRequest setPredicate:predicate];
  5. Выберите победителя.

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

    MyClass *prevObject;
    for (MyClass *duplicate in dupes) {
        if (prevObject) {
            if ([duplicate.uniqueProperty isEqualToString:prevObject.uniqueProperty]) {
                if ([duplicate.createdTimestamp compare:prevObject.createdTimestamp] == NSOrderedAscending) {
                    [context deleteObject:duplicate];
                } else {
                    [context deleteObject:prevObject];
                    prevObject = duplicate;
                }
            } else {
                prevObject = duplicate;
            }
        } else {
            prevObject = duplicate;
        }
    }

    Не забудьте устанавливать объем партии на выборке и каждый раз, когда Вы достигаете конца пакета, сохраняете контекст.

Контрольная точка

В этой точке Ваше приложение может детерминировано удалить двойные записи.

Установка: Откройте предыдущее не, iCloud включил версию Вашего приложения на двух устройствах.

Тест: Создайте несколько из тех же записей на обоих устройствах. Обновление к новой версии приложения на обоих устройствах. После того, как оба устройства переместили свои хранилища на iCloud (см. Мигрирующие Пользовательские Данные к iCloud для больше о миграции), дедупликация была выполнена, и оба устройства передали эти изменения в iCloud, проверьте, чтобы удостовериться, что нет никакой копии или недостающих записей.

Выполнение миграций схемы

Во время разработки Вашего приложения и между версиями, можно изменить Базовую Модель данных, определяющую объекты. Можно использовать вызванную миграцию схемы процесса для миграции существующих данных приложения для использования новой модели. При использовании хранилища SQLite с iCloud хранилище поддерживает только легкую миграцию. (Для больше о легкой миграции, посмотрите Легкую Миграцию в Базовом Руководстве по программированию Управления версиями и Миграции данных Модели данных.), Поскольку поддерживающие iCloud Базовые приложения Данных не могут сохранить изменения между различными версиями Вашего приложения, использующими использование различные схемы, Ваше приложение нагонит, и ранее также новые версии объединятся в изменениях более старой версии только после того, как это было обновлено к той же версии.

NSURL *documentsDirectory = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
NSURL *storeURL = [documentsDirectory URLByAppendingPathComponent:@"CoreData.sqlite"];
NSError *error = nil;
NSPersistentStoreCoordinator *coordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:<# your managed object model #>];
NSDictionary *storeOptions = @{NSPersistentStoreUbiquitousContentNameKey: @"MyAppCloudStore",
                            NSMigratePersistentStoresAutomaticallyOption: @YES,
                                  NSInferMappingModelAutomaticallyOption: @YES};
NSPersistentStore *store = [coordinator addPersistentStoreWithType:NSSQLiteStoreType
                                                     configuration:nil
                                                               URL:storeURL
                                                           options:storeOptions
                                                             error:&error];
NSURL *finaliCloudURL = [store URL];

Контрольная точка

В этой точке Ваше приложение может гладко выполнить миграции схемы с поддерживающим iCloud персистентным хранилищем.

Установка: Создайте вторую версию своего приложения с обновленной схемой, это совместимо с легкой миграцией.

Тест: Установите первую версию приложения на устройстве. Выполните действия, создающие записи и устанавливающие атрибуты, отличающиеся во второй версии Вашей схемы. Используйте второе устройство, выполняющее ту же версию приложения, чтобы проверить, что записи были сохранены к iCloud. Тогда установите и выполните обновленную версию приложения на Вашем устройстве. Проверьте, что записи мигрировали правильно.

Удаление поддерживающего iCloud Персистентного Хранилища

При разработке приложения (и иногда в реальном использовании), Вы, возможно, должны были бы временно или постоянно удалили бы свое поддерживающее iCloud персистентное хранилище. Существует три вида удаления хранилища: первое, восстанавливая от iCloud, удаляет локальное хранилище и воссоздает его от данных в iCloud. Вторая, отключающая персистентность iCloud, говорит Базовым Данным прекращать сохранять локальные данные к iCloud и не удаляет данных. Наконец, запуск вытирает данные Вашего приложения с Ваших устройств и с iCloud и является безусловно самым разрушительным.

Восстановление от iCloud

Чтобы удалить локальные данные и запуститься новый с существующих записей в iCloud, передайте NSPersistentStoreRebuildFromUbiquitousContentOption опция со значением @YES когда Вы добавляете свое поддерживающее iCloud персистентное хранилище к персистентному координатору хранилища. Включайте любые опции iCloud, которые Вы обычно включаете.

Отключение Персистентности iCloud

Чтобы мешать Вашему хранилищу сохраниться к iCloud, Вы просто не опускаете NSPersistentStoreUbiquitousContentNameKey опция, когда Вы добавляете свое персистентное хранилище. Чтобы полностью удалить повсеместные метаданные и отключить персистентность iCloud, вместо этого переместите свое хранилище на новое расположение и передайте NSPersistentStoreRemoveUbiquitousMetadataOption опция со значением @YES в Вашем вызове к migratePersistentStore:toURL:options:withType:error:.

Запуск

Для удаления хранилища постоянно из iCloud и каждой коллеги (включая текущее устройство) вызовите removeUbiquitousContentAndPersistentStoreAtURL:options:error: метод класса для NSPersistentStoreCoordinator класс. Этот метод синхронен, полагается на сетевую достижимость и потенциально продолжителен. Вы не должны использовать свое персистентное хранилище до возвратов метода. В той точке, Базовых переходах Данных к пустому хранилищу.