2012-01-26 3 views
6

Я настраиваю базовую службу синхронизации для iPad-приложения, которое я разрабатываю. Цель состоит в том, чтобы данные были согласованы в нескольких экземплярах iPad-приложения, а также имели доступную только для чтения информацию о данных в Интернете, и, следовательно, распространяли пользовательское решение.Core Data Sync - Отслеживание удаленных объектов

Ток заключается в следующем:

  • Каждый объект имеет поле A «создано», «модифицированные» и «UUID», которые автоматически обновляются Core Data
  • На синхронизации, каждого объекта с создано или измененная дата после того, как последняя дата синхронизации была сериализована в JSON и отправлена ​​на сервер
  • Сервер сохраняет любые изменения в базе данных MySQL с использованием UUID с клиентским кодом как ПК (при наличии конфликта он использует только недавно измененные сущность как «истинная» версия, ничего необычного там) и отправляет обратно все обновленные объекты клиенту
  • Затем клиент сливает эти изменения обратно в Core Data DB

Это все, кажется, работает нормально. Моя проблема заключается в том, как отслеживать удаленные объекты с помощью этого метода? Я предполагаю, что я могу добавить «удаленный» флаг для каждого объекта и установить его каждый раз, когда клиент удалит что-то, затем я могу нажать это изменение на сервер с остальными данными синхронизации. Как только синхронизация будет завершена, клиент может фактически удалить эти объекты. Мои вопросы:

  • Могу ли я переопределить методы удаления основных данных, чтобы автоматически установить этот флаг?
  • Должно ли это потребовать неограниченное количество всех удаленных объектов на сервере? Мы не будем знать, когда каждый клиент синхронизировал и фактически удалил каждый объект (я в настоящее время не отслеживаю экземпляры клиента)
  • Есть ли лучший способ сделать это?

ответ

5

Как насчет сохранения таблицы истории дельты с UUID и созданного/обновленного/удаленного поля, возможно, с номером ревизии для каждого обновления? Таким образом, вы сохраняете небольшой контрольный список изменений с момента последней успешной синхронизации.

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

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

Вы можете использовать insertedObjects, updatedObjects, методы deletedObjects NSManagedObjectContext для создания объектов дельты перед каждым сохранить порядок :)

Моих 2 цента

+0

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

1

Что касается второго вопроса: Вы можете спроектировать это так, чтобы сервер Безразлично Если вам нужно, нужно хранить удаленные записи. Пусть каждое приложение знает, хранится ли на данном сервере заданный фрагмент данных (на основе его UUID) (например, добавьте свойство existOnServer или аналогичный). Это начинается с false, когда новый элемент создается в приложении, но установлен в true, как только он был синхронизирован с сервером в первый раз.Таким образом, если приложение попытается выполнить синхронизацию позже, но UUID не найден, вы можете различать два случая: Если existsOnServer имеет значение false, тогда этот элемент будет создан и должен быть синхронизирован с сервером, но если это правда то это может означать, что он уже был на сервере раньше, но теперь удален, поэтому вы также можете удалить его в приложении.

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

1

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

Я позаботился об этой проблеме несколькими способами раньше. Вот одна из возможностей:

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

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

Конечно, вы можете вернуть удаленные объекты клиенту, чтобы они знали, что нужно удалить, но если вы не хотите хранить копию на сервере, вам нужно будет сделать некоторое предположение, что клиенты будут обновляться в течение некоторого времени Рамка. Затем вы можете собрать мусор после истечения этого временного интервала.

Я не очень люблю это решение. Если ваши данные слишком тяжелы, чтобы запросить все объекты для полной синхронизации, вы можете использовать свою текущую стратегию слияния для создания и обновления, а затем запустить отдельный вызов для проверки удаленных элементов. Этот вызов может просто запрашивать все идентификаторы, которые клиент должен иметь на устройстве. Он может удалить те, которые не существуют. ИЛИ он может отправить все идентификаторы на клиенте и вернуть список идентификаторов для удаления.

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

1

Вы можете взглянуть на Cross-Platform Data Synchronization by Dan Grover, если вы этого не сделали. Это очень хорошо написанная статья о синхронизации и iOS.

О вопросы:

  1. Вы можете избежать удаления файла в Core Data и установить «удален флаг»: просто обновить файл вместо того, чтобы удалить его. Вы можете создать свой собственный метод удаления, который на самом деле вызовет и обновит флаг в записи.

  2. Всегда сохраняйте last_sync и last_updated для каждой записи на сервере и на каждом клиенте. Таким образом, вы всегда будете знать, когда кто-то что-то изменил, и если это изменение было синхронизировано или нет против «базы данных истинности».

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

-3

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

enter image description here

+1

Привет, Gulsherkhan, пожалуйста, не включайте изображения кода, вместо этого используйте код. – bummi

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