Мне нужно создать приложение, имеющее функциональность, похожую на приложение для контактов. Вы можете добавить контакт на клиентский iPhone и загрузить его на клиентский iPad. Если клиент обновляет контакт на своем iPad, он должен обновиться на своем iPhone.
Большая часть этого довольно прямолинейна. Я использую Parse.com
как мой задний конец и локально сохраняя контакты с помощью Core Data
. Единственная проблема, с которой я сталкиваюсь, заключается в управлении контактами, когда пользователь отключен.
Скажем, у меня есть iPhone и iPad. Обе они в настоящее время имеют одну и ту же версию онлайн-базы данных. Мой iPhone теперь отключен. Это 9AM.
В 10 утра я обновляю номер телефона для контакта на своем iPad. Это сохраняет изменения локально и онлайн. В 11:00 я обновляю адрес электронной почты для одного и того же контакта на своем iPhone, но я все еще не в сети.
В полдень мой iPhone подключается к Интернету и проверяет сервер на наличие изменений. Он видит, что его изменения более поздние, чем последнее обновление (проверка свойства updatedAt
timestamp), поэтому вместо того, чтобы загружать новый номер телефона для контакта (который является "устаревшим" ), он отменяет номер телефона вместе с адресом электронной почты адрес (обновляет новый номер телефона до старой версии, потому что он был отключен во время обновления номера телефона в 10 утра, и его изменения предположительно более свежие).
Как я могу управлять проблемами в сети/офлайн, с которыми сталкиваются, например, выше? Решением, о котором я могу думать, было бы сохранить обновленные временные метки для каждого атрибута для контакта, а не только для общего свойства updatedAt
для всего контакта, например. когда было обновлено имя, когда была обновлена фамилия, а затем вручную проверьте, имеет ли автономное устройство последние изменения для каждого атрибута вместо того, чтобы перезаписывать весь объект, но это кажется неаккуратным.
Я также думал о наличии свойства timestamp updatedLocally
и updatedOnline
для каждого объекта Core Data
. Таким образом, если эти два не совпадают, я могу выполнить проверку diff и использовать последний для конфликтов, но это все еще не похоже на самое чистое решение. Кто-нибудь еще сталкивался с чем-то похожим? Если да, то как вы его решили?
Псевдокод/Резюме для того, что я думаю? охватывает все тестовые примеры, но все еще не очень элегантно/полно:
2 Объекты на Parse.com: история контактов и контактов
Контакт имеет первый, последний, телефон, адрес электронной почты, онлайн-адрес
История контактов имеет первичный ключ для контакта для ссылок и те же атрибуты, но с историей. например first: [{value:"josue",onlineUpdate:"9AM"},{value:"j",onlineUpdate:"10AM"},{value:"JOSUEESP",onlineUpdate:"11AM"}]
1 Объект по основным данным, контакт:
Контакт имеет первый, последний телефон, адрес электронной почты, onlineUpdate и offlineUpdate (ВАЖНО: это только в Core Data, а не в Parse)
for every contact in parse database as onlineContact {
if onlineContact does not exist in core data {
create contact in core data
}
else {
// found matching local object to online object, check for changes
var localContact = core data contact with same UID as onlineContact
if localContact.offlineUpdate more recent than onlineContact.onlineUpdate {
for every attribute in localContact as attribute {
var lastOnlineValueReceived = Parse database Contact History at the time localContact.onlineUpdate for attribute
if lastOnlineValueReceived == localContact.attribute {
// this attribute did not change in the offline update. use latest available online value
localContact.attribute = onlineContact.attribute
}
else{
// this attribute changed during the more recent offline update, update it online
onlineContact.attribute = localContact.attribute
}
}
}
else if onlineContact.onlineUpdate more recent than localContact.offlineUpdate {
// another device updated the contact. use the online contact.
localContact = offlineContact
}
else{
// when a device is connected to the internet, and it saves a contact
// the offline/online update times are the same
// therefore contacts should be equivalent in this else statement
// do nothing
}
}
TL; DR: Как вы планируете структурировать своего рода систему контроля версий для онлайновых/оффлайновых обновлений без случайной перезаписи? Я хотел бы ограничить использование полосы пропускания до минимума.