Синхронизация ядра данных - нужна помощь с логикой

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

Сторона сервера

Поставщик хранилища

Как и во всех облачных синхронизирующих системах, хранение является главной частью головоломки. Есть много способов справиться с этим. Я мог бы настроить свой собственный сервер для хранения или использовать такой сервис, как Amazon S3, но, поскольку я начинаю с капиталом в 0 долларов, на данный момент платное решение для хранения данных не является жизнеспособным вариантом. Подумав, я решил договориться сDropbox (уже хорошо зарекомендовавший себя поставщик облачных приложений для синхронизации). Плюсы использования Dropbox:

Это бесплатно (для ограниченного количества места)Помимо того, что это служба хранения, она также выполняет синхронизацию облачных вычислений.Недавно они выпустили Objective-C SDK, который значительно облегчает взаимодействие с ним в приложениях Mac и iPhone.

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

Структура хранения

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

CloudSyncFramework
======> [app name]
==========> devices
=============> (device id)
================> deviceinfo
================> changeset
==========> entities
=============> (entity name)
================> (object id)

Краткое объяснение этой структуры:

Основная папка «CloudSyncFramework» (имя не определено) будет содержать отдельные папки для каждого приложения, использующего инфраструктуруКаждая папка приложения содержитприборы папка июридические лица папкаприборы папка будет содержать папку для каждого устройства, зарегистрированного в учетной записи. Папка устройства будет названа в соответствии с идентификатором устройства, полученным с помощью чего-то вроде[[UIDevice currentDevice] uniqueIdentifier] (на iOS) или серийный номер (на Mac OS).Каждая папка устройства содержит два файла:информация об устройстве а такжеревизия. информация об устройстве содержит информацию об устройстве (например, версию ОС, дату последней синхронизации, модель и т. д.) иревизия Файл содержит информацию об объектах, которые изменились с момента последней синхронизации устройства. Оба файла будут просто простыми NSDictionaries, заархивированными в файлы с использованиемNSKeyedArchiver.Каждый базовый объект данных имеет подпапку подюридические лица папкаВ каждой папке объекта каждый объект, который принадлежит этому объекту, будет иметь отдельный файл. Этот файл будет содержать словарь JSON с парами ключ-значение.

Синхронная синхронизация

Это одна из областей, где я почти не знаю.Как бы я обрабатывал 2 устройства, подключающихся и синхронизирующихся с облаком одновременно? Похоже, что существует высокий риск нарушения синхронизации или даже повреждения данных.

Обработка миграций

Еще раз, еще одна невежественная область здесь.Как бы я справился с миграциями модели управляемых объектов Core Data? Кажется, проще всего здесь просто очистить хранилище облачных данных и загрузить новую копию данных с устройства, которое прошло процесс миграции, но это кажется несколько рискованным, и, возможно, найдется лучший способ.

Сторона клиента

Преобразование NSManagedObjects в JSON

Преобразование атрибутов в JSON не очень сложная задача (для этого существует множество кода, плавающего в Интернете). Отношения являются ключевой проблемой здесь. Вэтот Пост Stackoverflow, Маркус Зарра публикует код, в котором сами объекты отношений добавляются в словарь JSON. Однако он упоминает, что это может вызвать бесконечный цикл в зависимости от структуры модели, и я не уверен, будет ли это работать с моим методом, потому что я сохраняю каждый объект как отдельный файл.

Я пытался найти способ получить идентификатор в виде строки дляNSManagedObject, Тогда я мог бы сохранить отношения в JSON как массив идентификаторов. Самая близкая вещь, которую я нашел, была[[managedObject objectID] URIRepresentation], но на самом деле это не идентификатор объекта, это скорее место для объекта в постоянном хранилище, и я не знаю, достаточно ли его конкретно для использования в качестве ссылки для объекта.

Я предполагаю, что мог бы сгенерировать строку UUID для каждого объекта и сохранить ее как атрибут, но я открыт для предложений.

Синхронизация изменений в облаке

Первое (и до сих пор лучшее) решение, которое пришло мне в голову, было прислушиваться кNSManagedObjectContextObjectsDidChangeNotification чтобы получить список измененных объектов, затем обновите / удалите / вставьте эти объекты в облачное хранилище данных. После того, как изменения были сохранены, мне нужно обновитьревизия файл для каждого другого зарегистрированного устройства, чтобы отразить вновь измененные объекты.

Здесь возникает одна проблема:Как бы я справился с неудачной или прерванной синхронизацией?, У меня есть одна идея: сначала перенести изменения во временный каталог в облаке, а затем, если он был подтвержден как успешный, объединить его с основными данными в облаке, чтобы прерывание в середине синхронизации не повредило данные. Затем я хотел бы сохранить записи объектов, которые должны быть обновлены в облаке, в файл plist или что-то еще, чтобы их можно было проталкивать при следующем подключении приложения к Интернету.

Получение измененных объектов

Это довольно просто, устройство загружает своиревизия файл, выясняет, какие объекты нужно обновить / вставить / удалить, затем действует соответственно.

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

ОБНОВИТЬ

После долгих раздумий и прочтения предложений TechZens я придумал некоторые модификации моей концепции.

Самое большое изменение, которое я придумал, - сделать так, чтобы каждое устройство имелоотдельный хранилище данных в облаке. По сути, каждый раз, когда контекст управляемого объектаэкономит (спасибо TechZen), он загрузит изменения в хранилище данных этого устройства. После того, как эти изменения будут обновлены, он создаст файл «changeset» с деталями изменений и сохранит его в папках наборов изменений ДРУГИХ устройств, которые используют приложение. Когда другие устройства подключаются к синхронизации, они проходят через папку наборов изменений и применяют каждый набор изменений к локальному хранилищу данных, а затем обновляют свои соответствующие хранилища данных в облаке.

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

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

Ответы на вопрос(0)

Ваш ответ на вопрос