2009-07-17 19 views
8

Estoy tratando de escribir una aplicación de datos básicos para el iPhone que utiliza una fuente de datos externa. Realmente no estoy usando Core Data para persistir en mis objetos, sino más bien para la administración del ciclo de vida del objeto. Tengo una idea bastante buena sobre cómo usar los datos centrales para los datos locales, pero me he encontrado con algunos problemas con los datos remotos. Solo usaré la API de Flickr como ejemplo.Patrones para acceder a datos remotos con Core Data?

Lo primero es que si necesito decir, una lista de las fotos recientes, tengo que tomarlas de una fuente de datos externa. Después de recuperar la lista, parece que debo iterar y crear objetos administrados para cada foto. En este punto, puedo continuar en mi código y usar la API estándar de datos principales para configurar una solicitud de recuperación y recuperar un subconjunto de fotos sobre, por ejemplo, perros.

Pero, ¿qué sucede si luego quiero continuar y recuperar una lista de las fotos del usuario? Dado que existe la posibilidad de que estos dos conjuntos de datos se crucen, ¿tengo que realizar una solicitud de recuperación de los datos existentes, actualizar lo que ya está allí y luego insertar los nuevos objetos?

-

En el patrón mayor, me gustaría simplemente tienen estructuras de datos independientes para cada uno de estos conjuntos de datos y acceder a ellos de manera apropiada. Un conjunto de Fotos recientes y un conjunto de Fotos de usuarios. Pero dado que el patrón general de Core Data parece ser utilizar un contexto de objeto gestionado, parece (podría estar equivocado) que tengo que fusionar mis datos con el conjunto principal de datos. Pero parece una gran cantidad de sobrecarga solo para tomar una lista de fotos. ¿Debo crear un contexto de objeto gestionado separado para el conjunto diferente? ¿Deberían utilizarse los datos centrales aquí?

Creo que lo que encuentro atractivo para Core Data es que antes (para un servicio web) solicitaba ciertos datos y los filtraba en la solicitud o los filtraba en código y producía una lista que usaría . Con Core Data, puedo obtener una lista de objetos, agregarlos a mi grupo de servidores (actualizando los objetos antiguos según sea necesario) y luego consultarlos. Un problema, puedo ver con este enfoque, sin embargo, es que si los objetos se eliminan externamente, no puedo saberlo, ya que guardo mis datos anteriores.

¿Estoy lejos de la base aquí? ¿Hay algún patrón que las personas sigan para manejar datos remotos y datos básicos? :) He encontrado algunas publicaciones de personas que dicen que lo han hecho, y que les funciona, pero pocos ejemplos. Gracias.

+0

¿Puede ser más específico sobre lo que quiere? 'usa una fuente de datos externa' es muy vago. Parece que desea duplicar localmente una parte de una base de datos externa. ¿Necesita realizar cambios locales que se vuelvan a propocionar? ¿Qué hay de los conflictos? Este es un problema difícil y más detalles ayudarán a sugerir direcciones. –

+0

quizás un hilo obsoleto, estaría tentado de intentar buscar cosas en un hilo de fondo y escribirlas en la tienda persistente y hacer que las notificaciones se propaguen desde allí hasta el hilo principal, no estoy seguro de que funcionaría, pero estaría bien si lo hizo – bshirley

Respuesta

0

En una situación como esta, podría usar las instalaciones de archivo de Cocoa para guardar los objetos fotográficos (y un índice) en el disco entre sesiones, y simplemente sobrescribirlo todo cada vez que la aplicación llame a casa en Flickr.

Pero como ya está utilizando Core Data, y al igual que las características que proporciona, ¿por qué no modifica su modelo de datos para incluir un atributo "fuente" o "tipo de llamada"? En este momento, está creando implícitamente un conjunto de objetos con la fuente "API de Flickr", pero puede tratar las diferentes llamadas a la API como fuentes únicas y luego almacenarlas explícitamente.

Para manejar la eliminación, la forma más sencilla sería borrar el almacén de datos cada vez que se actualiza. De lo contrario, necesitaría iterar sobre todo y solo eliminar los objetos de la foto con nombres de archivo que no se incluyeron en los nuevos resultados.

Estoy planeando hacer algo similar a esto, así que espero que esto ayude.

PD: Si no está almacenando los objetos fotográficos entre sesiones, puede usar dos contextos diferentes y consultarlos por separado. Siempre que nunca se guarden, y la tienda central ya no tenga nada, funcionaría tal como lo describes.

2

Me parece que sus primeros instintos son correctos: debe usar fetchrequests para actualizar su tienda existente. El enfoque que utilicé para un importador fue el siguiente: obtener una lista de todos los archivos que son elegibles para la importación y almacenarla en algún lugar. Supongo que conseguir esa lista es rápido y liviano (solo un nombre y una URL o ID único), pero eso realmente importa algo llevará un poco más de tiempo y esfuerzo y el usuario puede abandonar el programa o querer hacer algo más antes de que toda la importación esté hecha.

Luego, en un hilo de fondo separado (esto no es tan difícil como suena gracias a NSRunLoop y NSTimer, google en "Datos principales: Importación eficiente de datos"), obtenga el primer elemento de esa lista, obtenga el objeto de Flickr o donde sea y búsquelo en la base de datos de Core Data (lea con atención la Guía de programación de predicados de Apple sobre la configuración de NSFetchRequests eficiente y en caché). Si el objeto remoto ya vive en Core Data, actualice la información según sea necesario, si no inserte. Cuando haya terminado, elimine el elemento de la lista que se importará y continúe con el siguiente.

En cuanto al problema de los objetos que se han eliminado en el almacenamiento remoto, existen dos soluciones: sincronización periódica o sincronización a demanda a la demanda. ¿Importar una foto de Flickr significa importar la cosa original y todos sus metadatos (no sé cuál es la política con respecto a la propiedad, etc.) o solo quieres importar una miniatura y algo de información? Si almacena todo localmente, puede ejecutar un cheque cada pocos días o semanas para ver si todo en su tienda local también está presente de forma remota: si no, el usuario puede decidir guardar la foto de todos modos o eliminarla. Si solo almacena miniaturas o vistas previas, necesitará conectarse a Flickr cada vez que el usuario quiera ver la imagen completa. Si se ha eliminado, puede informar al usuario y eliminarlo también localmente, o marcarlo como no accesible.

2

Puede probar una combinación de dos cosas. Esta estrategia le dará una interfaz donde obtendrá los resultados de una NSFetchRequest dos veces: una vez sincrónicamente, y una vez más cuando los datos se hayan cargado desde la red.

  1. crear una subclase de NSFetchRequest que tiene una propiedad de bloque adicional a ejecutar cuando el fetch es terminado. Esto es para su solicitud asincrónica a la red. Vamos a llamar al FLRFetchRequest

  2. Cree una clase a la que pase esta solicitud. Llamémoslo FLRPhotoManager. FLRPhotoManager tiene un método executeFetchRequest: que toma un instancia de la FLRFetchRequest y ...

    1. Colas de su solicitud de red en base a la solicitud de búsqueda y pasa a lo largo de la solicitud retenido podido recuperar para ser procesados ​​de nuevo cuando la solicitud de red es terminado.
    2. Ejecuta la solicitud de recuperación contra su caché CoreData e inmediatamente devuelve los resultados.
    3. Ahora cuando finalice la solicitud de red, actualice su caché de datos centrales con los datos de red, ejecute de nuevo la solicitud de recuperación contra la caché y esta vez extraiga el bloque de FLRFetchRequest y pase los resultados de esta solicitud de recuperación al bloque , completando la segunda fase.

Este es el mejor patrón que he llegado con, pero al igual que usted, yo estoy interesado en las opiniones de otros.

+0

, también he encontrado un enfoque similar. Me pregunto si ya has encontrado una mejor manera de hacerlo. – Petar