Хранение основных объектов данных в нескольких хранилищах

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

Но я также хочу предложить возможность работать с данными «в автономном режиме», то есть сохраняя локальное постоянное хранилище на iPad. До сих пор я читал, что могу сделать это в некоторой степени, используя функцию миграции координатора постоянного хранилища, но это, похоже, означает, что старое хранилище становится недействительным. Кроме того, я не обязательно хочу переместить весь магазин в «офлайн», а только его часть: используя простой пример «отдела компании», который предлагает Apple, я хочу, чтобы пользователи могли проверить один отдел, а также со всеми сотрудниками, связанными с этим отделом (и всеми атрибутами, связанными с каждым сотрудником). Затем пользователи могут работать с данными отдела локально на своем iPad и через некоторое время синхронизировать эти изменения обратно в постоянное хранилище сервера.

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

Из всего, что я видел до сих пор, похоже, что нет простого способа синхронизировать или копировать постоянные хранилища Core Data, это справедливая оценка?

Так что мне действительно нужно написать кусок кода, который делает следующее:

  • получить объект «А» через MOC
  • получить все объекты во всех сущностях, которые имеют отношение к объекту "A"
  • создать экземпляр нового MOC для целевого постоянного хранилища
  • для каждого полученного объекта проверьте целевое хранилище, существует ли объект
  • если объект существует, перезапишите его атрибутами из объекта, полученного на шагах 1 и 2.
  • если объект не существует, создайте его и установите все атрибуты в соответствии с объектом, полученным на шагах 1 и 2.

Хотя это не самая сложная вещь в мире, я бы все же подумал, что это требование для «онлайн / оффлайн редактирования» достаточно распространено, чтобы некоторые стандартные функции были доступны для синхронизации частей постоянных хранилищ?

Ваша точка зрения очень ценна, спасибо, da_h-man


person da_h-man    schedule 04.09.2012    source источник
comment
На самом деле это самая сложная вещь в мире.   -  person Rob Reuss    schedule 04.09.2012


Ответы (3)


Я просто пошутил с комментарием выше. Вы действительно описываете довольно сложную проблему - очень сложно добиться такого рода синхронизации, и редко в любой среде разработки будет готовое решение, которое будет "просто работать". Я думаю, что ваше описание псевдокода выше является довольно точным описанием того, что вам нужно будет сделать. Хотя часть работы по обходу отношений и проверке существующих объектов может быть обобщена, вы говорите о некоторых потенциально сложных ситуациях обработки исключений — например, если обновляется объект, и только 1 из 5 связанных объектов каким-то образом устарел. , вы выбрасываете обновление или применяете его часть? Вы говорите, что «параллелизм» не является частью вопроса, но если несколько пользователей могут «извлекать» объекты одновременно, если вы не планируете иметь для них механизм блокировки, у вас возникнут конфликты при попытке сделать обновления.

Что-то, на что стоит обратить внимание, — это новые функции в Core Data для использования iCloud — я сомневаюсь, что это поможет с вашей проблемой, но обычно это связано.

Поскольку вы хотите быть в сети со своими данными, еще одна вещь, которую следует учитывать, — это то, подходят ли Core Data для вашей проблемы в целом. Поскольку Core Data в значительной степени является технологией, разработанной для поддержки шаблона пользовательского интерфейса и MVC в целом, если ваши потребности в данных не привязаны конкретно к пользовательскому интерфейсу, вы можете рассмотреть другой тип решения БД.

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

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

person Rob Reuss    schedule 04.09.2012
comment
Привет, Роб, спасибо за ответ. Так что это действительно придется делать вручную. Ург. Тем не менее, параллелизм не должен быть проблемой — я могу добавить проверенное свойство к объекту отдела. Все сотрудники и т. д. могут быть назначены только одному отделу, поэтому я должен быть в порядке, пока применяю некоторую логику к возможности регистрации прихода и ухода. Я проверю TouchDB, возможно, это действительно лучший подход, но мне нравится функциональность Core Data, и мне придется работать с большими наборами, то есть с тысячами сотрудников, где я хочу минимизировать объем данных, фактически загружаемых в приложение. - person da_h-man; 05.09.2012
comment
Было бы неплохо, если бы у вас была базовая настройка модели в Core Data, чтобы запустить некоторые тесты производительности, заполнив вашу модель тысячами объектов, и убедиться, что вы можете получить требуемую производительность. В зависимости от мощности устройств, на которых вы его запускаете, и сложности запросов, которые требуются для серверной части SQLite, вы можете столкнуться с проблемами производительности. Core Data — это не БД, и это становится очевидным для тысяч объектов. Мне очень нравится Core Data — он решает много проблем, но не масштабируется. - person Rob Reuss; 07.09.2012

Из того, что я видел до сих пор, я считаю, что лучшим подходом является RestKit. Он предлагает оболочку Core Data, которая использует JSON для перемещения данных между удаленными и локальными хранилищами. Я еще не пробовал его полностью, но, судя по документации, он звучит довольно мощно и идеально подходит для моих нужд.

person da_h-man    schedule 15.09.2012
comment
Хм. Изучая RestKit, я обнаружил две вещи: его исходный код меняется так часто, что несколько руководств и примеров по RestKit часто не работают и очень часто содержат ошибочный контент. Удивительно, как сильно меняется API... И, во-вторых, он не делает того, что я хочу, - использовать HTTP для запросов к удаленно расположенным постоянным хранилищам Core Data. Это позволяет мне использовать доступные извне веб-сервисы для отдыха и хранить их в Core Data... хотя на самом деле я не видел в этом пользы. В любом случае, нет возможности получить удаленный контент Core Data. Вздох. - person da_h-man; 16.09.2012
comment
Я посмотрел на RestKit и пришел примерно к тем же выводам, что и вы, - кроме того, я чувствовал, что собираюсь сделать свою модель подходящей для JSON способами, которые не имеют смысла. Я сейчас работаю над проектом, который включает удаленную передачу объектов, поэтому, если вы что-нибудь выяснили, дайте мне знать. Я продвигаюсь вперед с архитектурой на основе сообщений, которая сохраняет большую часть данных в файлах — хотелось бы использовать Core Data, но это просто не подходит. - person Rob Reuss; 25.09.2012
comment
Эй, Роб, сейчас я пытаюсь (и если мне это удастся, я с радостью поделюсь своим кодом, хотя в любом случае это может быть довольно просто), это использовать WebAppKit (очень простой фреймворк HTTP-сервера) на сервере / MacOS, чтобы взять локальный Реализация Core Data и отправить его на устройство iOS через JSON. По-видимому, существует достаточное количество фреймворков JSON-to-Core-Data, поэтому все должно быть довольно просто. - person da_h-man; 26.09.2012
comment
WebAppKit выглядит многообещающе. Я делаю что-то подобное, используя CocoaHTTPServer - мое решение предназначено только для iOS, поэтому WebAppKit не подходит (похоже, это только для Mac OS). Я также посмотрел http://codeworkshop.net/posts/a-routing-cocoahttpserver - работает как описано, но решил развернуть свою собственную структуру, ориентированную на сообщения, поверх базового HTTP. Я использовал HTTP, но мне не нужно предлагать доступ через веб-браузер, поэтому нет необходимости реализовывать мой интерфейс с помощью путей URL. Сообщения (заархивированные NSObjects) передаются по корневому пути и содержат всю внутреннюю информацию о маршрутизации/обработке. - person Rob Reuss; 27.09.2012
comment
Звучит интересно - пожалуйста, держите меня в курсе ваших успехов! - person da_h-man; 28.09.2012

Вы обязательно должны проверить следующие вещи:

Parse.com — облачное хранилище данных

PFIncrementalStore https://github.com/sbonami/PFIncrementalStore — подкласс NSIncrementalStore что позволяет вашему координатору постоянного хранилища хранить данные как локально, так и удаленно (в облаке Parse) одновременно.

Все эти вещи хорошо документированы. Также Parse.com собирается выпустить SDK локального хранилища данных iOS http://blog.parse.com/2014/04/30/take-your-app-offline-with-parse-local-datastore/, который поможет сохранить ваши данные. синхронизировано.

person kas-kad    schedule 14.05.2014