2009-07-17 2 views
8

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

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

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

-

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

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

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

+0

Можете ли вы уточнить, что вы хотите? «использует внешний источник данных» очень расплывчато. Похоже, вы хотите локально отобразить часть внешней базы данных. Вам нужно внести местные изменения, которые будут переданы обратно? Как насчет конфликтов? Это сложная проблема, и более подробная информация поможет предложить направления. –

+0

, возможно, затхлый поток, у меня возникнет соблазн попытаться найти что-то в фоновом потоке и записать их в постоянный магазин и получить от них уведомления до основного потока - не уверен, что это сработает, но было бы неплохо если бы это было – bshirley

ответ

0

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

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

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

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

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

2

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

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

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

2

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

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

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

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

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

+0

У меня также появился простой подход - интересно, нашли ли вы лучший способ сделать это сейчас? – Petar

Смежные вопросы