Лучшая стратегия для синхронизации данных в приложении для iPhone

Я работаю над обычным приложением для iPhone, которое извлекает данные с сервера (XML, JSON и т. Д.), И мне интересно, как лучше всего реализовать синхронизацию данных. Критериями являются скорость (меньше сетевого обмена данными), надежность (восстановление данных в случае сбоя обновления), автономный доступ и гибкость (адаптируется, когда структура базы данных изменяется незначительно, как новый столбец). Я знаю, что это варьируется от приложения к приложению, но вы, ребята, не могли бы поделиться своей стратегией / опытом?

Что касается меня, я думаю о чем-то вроде этого:

1) Сохранить дату последнего изменения в iPhone

2) После запуска отправьте сообщение вида getNewData.php? LastModifiedDate = ...

3) Сервер обработает и отправит обратно только измененные данные с последнего раза.

4) Эти данные отформатированы так:

<+><data id="..."></data></+> // add this to SQLite/CoreData

<-><data id="..."></data></-> // remove this

<%><data id="..."><attribute>newValue</attribute></data></%> // new modified value

Я не хочу делать ‹+>, ‹->,‹%> ... также для каждого атрибута, потому что это было бы слишком сложно, поэтому, вероятно, при получении поля ‹%> я бы просто удалил данные с указанным идентификатором, а затем добавьте его снова (при условии, что здесь идентификатор не является автоматически увеличивающимся полем).

5) Как только все будет загружено и обновлено, я обновлю поле Дата последнего изменения.

Основная проблема этой стратегии: если сеть выходит из строя, когда я что-то обновляю => Дата последнего изменения еще не обновлена ​​=> в следующий раз, когда я перезапускаю приложение, мне придется повторить то же самое снова. Не говоря уже о потенциально противоречивых данных. Если я использую временную таблицу для обновления и сделаю все это атомарным, это сработает, но опять же, если обновление будет слишком длинным (много изменений данных), пользователю придется долго ждать, пока не станут доступны новые данные. Должен ли я использовать Last-Modified-Date для каждого поля данных и обновлять данные постепенно?


person iamj4de    schedule 06.06.2010    source источник


Ответы (3)


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

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

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

Если вы пытаетесь оптимизировать (свести к минимуму) передачу данных, вы можете рассмотреть вариант, отличный от XML, поскольку XML довольно подробен. Или, по крайней мере, вы можете обменять удобочитаемость XML на пространство, сделав каждое имя элемента и атрибут как можно меньше и удалив все ненужные пробелы.

person Shaggy Frog    schedule 06.06.2010

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

По нашему опыту, довольно большие обновления (10 КБ) могут быть загружены довольно быстро, если сервер достаточно быстрый. Нет особой необходимости разбивать обновления на мелкие кусочки. Но, конечно, не помешает попытаться минимизировать объем передаваемых данных, сохраняя более подробную информацию о «последнем обновлении».

(И определенно вам следует использовать JSON, а не XML в качестве представления передаваемых данных.)

person Hot Licks    schedule 19.12.2011

Интересно, рассматривали ли вы возможность использования Sync Framework для управления синхронизацией. Если вас это интересует, вы можете взглянуть на проект с открытым исходным кодом, службу синхронизации OpenMobster. Вы можете выполнять следующие операции синхронизации

  • двусторонний
  • односторонний клиент
  • одностороннее устройство
  • загрузка

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

Кроме того, изменения в облаке синхронизируются с помощью push-уведомлений, поэтому данные всегда актуальны, даже если они хранятся локально.

В твоем случае,

Criteria are speed (less network data exchange), robustness (data recovery in case update fails), offline access
  • Скорость: только изменения отправляются по сети в обоих направлениях.

  • Надежность: данные хранятся в хранилище транзакций, таком как sqlite, и любые неудачные обновления передаются в полезной нагрузке SyncML. Только успешные операции обрабатываются, а неудачные операции повторяются во время следующей синхронизации.

Вот ссылка на проект с открытым исходным кодом: http://openmobster.googlecode.com

Вот ссылка на синхронизацию приложений iPhone: http://code.google.com/p/openmobster/wiki/iPhoneSyncApp

person openmobster    schedule 18.03.2012