iCloud + CoreData - как избежать дублирования предварительно заполненных данных?

У меня проблема с приложением iCloud для обувной коробки, и я надеюсь, что кто-нибудь сможет мне помочь (я потратил много часов на борьбу с этим напрасно).

Приложение: - Простое приложение в стиле библиотеки, содержащее набор категорий (Cat1 .. CatN), каждая из которых содержит элементы (Item1 ... ItemM). Я использовал Apple iPhoneCoreDataRecipes для настройки стека iCloud CoreData.

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

Вот что я делаю - как только мой persistentStoreCoordinator настроен, я отправляю уведомление

dispatch_async(dispatch_get_main_queue(), ^{
    [[NSNotificationCenter defaultCenter]
        postNotificationName: @"RefetchAllDatabaseData"
                      object: self
                    userInfo: nil];
    });

, которое получает мой MasterViewController. При получении уведомления MasterViewController проверяет количество категорий в хранилище. Если количество доступных категорий равно 0 - вставляются предварительно заполненные категории.

К вашему сведению - я использую NSMergeByPropertyObjectTrumpMergePolicy для моего ManagedObjectContext

Проблема: Это хорошо работает для 1-го устройства. Но для 2-го устройства категории по умолчанию из iCloud часто принимаются позже, чем был установлен persistentStoreCoordinator (и категории по умолчанию, вставленные 2-м устройством).В итоге у меня есть 2 набора категорий с одинаковыми именами на обоих устройствах.

Есть идеи, как это можно решить?

Пробные решения: Я пробовал 2 стратегии, чтобы решить эту проблему. Оба начинаются одинаково. После того, как я позвоню

[moc mergeChangesFromContextDidSaveNotification: note];

, я позвоню

[self materializeKeysWithUserInfo: note.userInfo forContext: moc];

, большое спасибо Хосе Инес Канту Аррамбиде из https://devforums.apple.com/thread/126670?start=400&tstart=0 за его ссылочный код - In сущность

materializeKeysWithUserInfo:forContext:

получает ManagedObjectIds из note.userInfo и извлекает соответствующие объекты из ManagedObjectContext, помещая их в словарь.

Стратегия 1:

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

Эта стратегия эффективно удаляет дубликаты на оба устройства еще до того, как они появятся в пользовательском интерфейсе НО

1) элементы с 1-го устройства теряются на 2-м устройстве - когда они переходят на 2-е устройство, их родительская категория отсутствует, а их поле категории равно нулю, поэтому Я не знаю, куда их положить.

2) через некоторое время предметы, потерянные на 2-м устройстве, также теряются на первом из-за конфликтов.

3) некоторые элементы, исходящие от 2-го устройства, также потеряны из-за конфликтов.

Я пытался предпочесть старые категории новым, но это не дало никакого эффекта

Стратегия 2:

  • Все мои категории имеют отметки времени создания.
  • Для всех категорий устаревшее логическое поле установлено на НЕТ при создании
  • При вставке из iCloud получить пары категорий с одинаковым именем, если таковые имеются
  • Выбрать старые повторяющиеся категории
  • перемещают свои элементы в новые повторяющиеся категории
  • отмечают старые категории с помощью obsolete = YES

Эта стратегия почти всегда удаляет дубликаты на обоих устройствах даже до того, как они появятся в пользовательском интерфейсе НО

большинство (или все) элементы с обоих устройств теряются из-за множества конфликтов по категориям и элементам.

Некоторые заключительные мысли:

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

В моих тестах оба устройства работали одновременно. Я не могу игнорировать случай, когда счастливый пользователь, который только что купил свое 2-е iDevice, устанавливает мое приложение на 2-е устройство (с Tre 1-м устройством, на котором запущено приложение) и теряет все свои элементы в считанные минуты.

Есть идеи, как можно разрешить эту ситуацию? Как вы думаете, iCloud + CoreData готов к производству?

Стратегия 3

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

iCloud не знает данных, которые существовали в базе данных до настройки iCloud - мое 2-е устройство получает элементы, вставленные на 1-е устройство в предварительно заполненных категориях, с категорией = nil.

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

15
задан Kostiantyn Sokolinskyi 1 February 2012 в 17:36
поделиться