У меня проблема с приложением для обувной коробки 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 за его код ссылки - по сути
materializeKeysWithUserInfo:forContext:
получает managedObjectIds из note.userInfo и извлекает соответствующие объекты из ManagedObjectContext, помещая их в словарь.
Стратегия 1:
- Все мои категории имеют метки времени создания.
- При вставке из iCloud, получить пары категорий с одинаковыми именами, если таковые имеются
- Выберите старые категории дубликатов
- переместить свои предметы в более новые категории дубликатов
- удалить старые повторяющиеся категории
Эта стратегия эффективно удаляет дубликаты на обоих устройствах даже до того, как они появятся в пользовательском интерфейсе НО
1) предметы с 1-го устройства теряются на 2-м устройстве - когда они попадают на 2-е устройство, их родительская категория отсутствует и их поле категории равно нулю, поэтому я не знаю, куда их поместить.
2) через некоторое время элементы, потерянные на втором устройстве, также теряются на первом из-за конфликтов.
3) некоторые предметы со 2-го устройства также теряются из-за конфликтов.
Я пытался предпочесть более старые категории новым, но это не дало никакого эффекта
Стратегия 2:
- Все мои категории имеют метки времени создания.
- Все категории имеют устаревшее логическое поле, установленное на NO при создании
- При вставке из iCloud, получить пары категорий с одинаковыми именами, если они есть
- Выберите старые категории дубликатов
- переместить свои предметы в новые двойные категории
- пометьте старые категории с устарело = ДА
Эти стратегии почти всегда удаляют дубликаты на обоих устройствах еще до того, как они появляются в интерфейсе пользователя НО
Большинство (или все) предметов с обоих устройств теряются из-за множества конфликтов по категориям и предметам.
Некоторые заключительные мысли:
Похоже, что эта стратегия не работает, поскольку мы начинаем одновременную смену контента на обоих устройствах, тогда как iCloud не подходит для такого шаблона.
В моих тестах оба устройства работали одновременно.Я не могу игнорировать случай, когда счастливый пользователь, который только что купил свой 2-й iDevice, устанавливает мое приложение на 2-е устройство (при котором приложение запускается на 1-м устройстве) и теряет все свои элементы в считанные минуты.
Есть идеи, как решить эту ситуацию?Как вы думаете, iCloud + CoreData готов к работе?
Стратегия 3
Я пытался поместить предварительно заполненную базу данных (копированиеэто от связки) к соответствующему пути.Это сработало частично - у меня больше нет дублирования предварительно заполненных категорий НО элементы, добавленные в предварительно заполненные категории, не синхронизируются между устройствами.
iCloud не знает о данныхкоторый существует в базе данных до установки iCloud - мое 2-е устройство получает элементы, вставленные на 1-е устройство в предварительно заполненные категории, с категорией = ноль.
Элементы в дополнительных категориях (а также сами категории) вставленыв хранилище после настройки iCloud правильно синхронизировать.