Шаблоны для доступа к удаленным данным с Core Data? - PullRequest
8 голосов
/ 18 июля 2009

Я пытаюсь написать приложение Core Data для iPhone, которое использует внешний источник данных. Я на самом деле не использую Core Data для сохранения своих объектов, а скорее для управления жизненным циклом объекта. У меня есть довольно хорошая идея о том, как использовать Core Data для локальных данных, но я столкнулся с несколькими проблемами с удаленными данными. Я просто использую API Flickr в качестве примера.

Во-первых, если мне нужно, скажем, список последних фотографий, мне нужно взять их из внешнего источника данных. После того, как я получил список, кажется, что я должен повторить и создать управляемые объекты для каждой фотографии. На этом этапе я могу продолжить работу со своим кодом и использовать стандартный API-интерфейс Core Data API для настройки запроса на выборку и получения подмножества фотографий, скажем, о собаках.

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

-

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

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

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

Ответы [ 3 ]

2 голосов
/ 21 ноября 2009

Мне кажется, что ваши первые инстинкты верны: вы должны использовать fetch-запросы для обновления вашего существующего магазина. Подход, который я использовал для импортера, был следующий: получить список всех файлов, которые можно импортировать, и сохранить его где-нибудь. Здесь я предполагаю, что получение этого списка является быстрым и легким (просто имя и URL или уникальный идентификатор), но для реального импорта чего-либо потребуется немного больше времени и усилий, и пользователь может выйти из программы или захотеть что-то сделать иначе, прежде чем весь импорт будет выполнен.

Затем в отдельном фоновом потоке (это не так сложно, как звучит благодаря NSRunLoop и NSTimer, Google на «Базовые данные: эффективный импорт данных»), получите первый элемент этого списка, получите объект из Flickr или где угодно и ищите его в базе данных Core Data (внимательно прочитайте Руководство по программированию Predicate Apple по настройке эффективных, кэшированных NSFetchRequests). Если удаленный объект уже находится в Базовых данных, при необходимости обновите информацию, если не вставите. Когда это будет сделано, удалите элемент из списка для импорта и перейдите к следующему.

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

2 голосов
/ 23 сентября 2010

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

  1. Создайте свой собственный подкласс NSFetchRequest, который принимает дополнительное свойство блока выполнить, когда выборка закончена. Это для вашего асинхронного запрос в сеть. Давай позвоним это FLRFetchRequest

  2. Создайте класс, в который вы переходите этот запрос. Давайте назовем это FLRPhotoManager. FLRPhotoManager имеет метод executeFetchRequest:, который принимает экземпляр FLRFetchRequest и ...

    1. Ставит ваш сетевой запрос в очередь на основе запроса на выборку и передает сохраненный запрос на выборку для повторной обработки после завершения сетевого запроса.
    2. Выполняет запрос на выборку для вашего кэша CoreData и немедленно возвращает результаты.
    3. Теперь, когда сетевой запрос завершится, обновите кеш основных данных сетевыми данными, снова запустите запрос выборки для кеша, и на этот раз вытащите блок из FLRFetchRequest и передайте результаты этого запроса выборки в блок. , завершая второй этап.

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

0 голосов
/ 10 ноября 2009

В такой ситуации вы можете использовать средства архивирования Cocoa для сохранения объектов фотографии (и индекса) на диск между сеансами и просто перезаписывать их все каждый раз, когда приложение вызывает Flickr.

Но так как вы уже используете Core Data и любите предоставляемые им функции, почему бы не изменить свою модель данных, включив в нее атрибут «source» или «callType»? В настоящий момент вы неявно создаете группу объектов с исходным кодом «Flickr API», но вы можете так же легко обрабатывать различные вызовы API как уникальные источники и затем сохранять их явно.

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

Я планирую сделать что-то подобное самому, поэтому я надеюсь, что это поможет.

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

...