2016-05-05 3 views
4

Мой вопрос связан с дельта-загрузкой, так как он был назван в WWDC 2014 Advanced CloudKit.CloudKit: CKFetchRecordChangesOperation, CKServerChangeToken и Delta Загрузить

Я пытаюсь сделать syncronization для моего приложения Core Data, которое является iPhone только сейчас (подумайте: есть только одно устройство активно). Таким образом, в основном приложение будет хранить пользовательские записи в облаке с одного и того же устройства, в большинстве случаев на данный момент.

У меня проблема с пониманием особенностей пользовательской зоны, которая основана на CKFetchRecordChangesOperation aka Delta Download.

Как я понял, у нас есть CKServerChangeToken для поддержания операций синхронизации (я имею в виду загружать только те записи, которые были добавлены/изменены/удалены другим устройством), как было представлено на WWDC. Но я не понимаю, что мы получаем этот токен только после CKFetchRecordChangesOperation, когда мы сохраняем записи в облаке, мы не получаем новый токен.

И если мы делаем выборку с текущим доступным токеном (поскольку он изменяется только после извлечения), мы получаем записи, которые были сохранены из нашей предыдущей операции сохранения. В основном мы получаем исправления, которые уже есть на нашем устройстве. Зачем? Я что-то упустил?

Что делать, если мы высеваем некоторые данные в облако (с устройства A), это оправдано для ситуации, когда устройство B извлекает записи зоны, но что делать, если устройство A? Скачайте все записи еще раз?

Я нашел recordChangeTag в CKRecord, это свойство можно использовать для разрешения конфликтов с местными объектами - неправдоподобные объектов (одинаковые или разные версии), если это кто-то может дать мне пример того, как мне нужно это сделать: сохранить recordChangeTag для Core Data, если сохранить запись в CloudKit в первый раз или как?

Отсутствие документации - такая головная боль.

+1

Я действительно открыл футляр с Apple об этой проблеме. Нет никакого смысла, что устройство сообщается об изменениях, которые были сделаны с устройства, используя 'CKFetchRecordChangesOperation'. Мне сказали ровно - так оно и есть. Таким образом, ваш код должен иметь дело с получением всех этих избыточных изменений записей. – rmaddy

+0

@rmaddy О, спасибо за эту информацию. Если вы напишете это как ответ, я соглашусь с ним, потому что нет других ответов, а ваш ближайший. –

+0

@rmaddy Я прочитал вашу дискуссию о яблочном devforum Рике, и я хочу спросить вас, вы попробовали обходное решение, предложенное PBK? Ссылка на обсуждение: https://forums.developer.apple.com/message/77233#77233 –

ответ

3

Я нашел время, чтобы написать ответ на этот вопрос. Я не буду вникать в реализацию, но я буду обсуждать эту концепцию.

CloudKit обеспечивает способ синхронизации данных между вашим устройством и сервером CloudKit. Что я использую, чтобы установить процесс синхронизации в моем случае только между iPhone и сервером (опять же, если у вас есть приложение iPhone + iPad, процесс требует больше шагов.):

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

Шаги:

1) Проверьте, если мой заказ зона существует

1.1) Если нет пользовательских зоны

1,2) Создать новую пользовательскую зону. (Необязательно: добавить записи)

1.3) изменение Refresh зоны маркеров

Вы можете обновить маркер изменения зоны: исполняющее CKFetchRecordChangesOperation, fetchRecordChangesCompletionBlock возвращается CKServerChangeToken сохранить его в UserDefaults (например) с помощью NSKeyedArchiver) ,Задачей этой операции является обновление токена, и оно выполняется в процессе завершения синхронизации.

2) Если есть пользовательские зоны уже

2,1) Получить изменения из зоны, используя ранее сохраненный маркер изменения зоны. (CKFetchRecordChangesOperation)

2.2) Обновление и удаление локальных записей.

2.3) Ток изменения зоны обновления.

2.4) Проверьте локальные изменения (я использую последнюю временную метку синхронизации облаков, чтобы проверить, какие записи были изменены после).

2.5) Загрузить записи в базу данных облачной комплект

2.6) изменение Обновить зоны маркер снова.

Я настоятельно рекомендую Ник Харрис серию статей: https://nickharris.wordpress.com/2016/02/09/cloudkit-core-data-nsoperations-introduction/

Вы найдете там и реализацию концепции дизайна. Это стоит прочитать. Надеюсь, кто-то найдет все это полезным.

+0

Спасибо, что нашли время, чтобы написать это! Это помогло мне с той же проблемой. Видео и документация WWDC от Apple не уточняют или не предупреждают об этой проблеме. Они продают CloudKit в качестве платформы отправки Бога, но есть так много тупиков и gotchas. – lostAtSeaJoshua

+0

Еще одно предложение решить эту проблему, если CoreData используется в качестве локального хранилища, заключается в том, что вы можете выполнить запрос на выборку со всеми «измененными записями», отправленными для 'CKFetchRecordChangesOperation'. Затем отфильтруйте записи на основе сравнения 'recordChangeTag', поэтому, даже если одни и те же записи возвращаются, они будут отфильтрованы и начнут обрабатывать фактические изменения. – lostAtSeaJoshua

+0

@lostAtSeaJoshua вы правы, у CloudKit есть хорошие возможности, но у вас нет документации по некоторым темам, например, синхронизация Core Data с iCloud была ... (и это так, но теперь это не имеет значения). Что касается фильтрации, да, вам нужна какая-то проверка записей. Но, как я вижу, 'CKFetchRecordChangesOperation' устарел уже ... https://developer.apple.com/reference/cloudkit/ckfetchrecordchangesoperation –