8
votes

Motifs d'accès à des données distantes avec des données de base?

J'essaie d'écrire une application de données de base pour l'iPhone qui utilise une source de données externe. Je n'utilise pas vraiment les données de base pour persister mes objets, mais plutôt pour la gestion du cycle de vie d'objet. J'ai une très bonne idée sur la manière d'utiliser les données de base pour les données locales, mais j'ai rencontré quelques problèmes avec des données à distance. Je vais simplement utiliser l'API de Flickr comme exemple.

La première chose à faire est que si j'ai besoin de dire, une liste des photos récentes, je dois les saisir à partir d'une source de données externe. Après avoir récupéré la liste, il semble que je voudrais itération et créer des objets gérés pour chaque photo. À ce stade, je peux continuer dans mon code et utiliser l'API Standard Core Data API pour configurer une demande de récupération et récupérer un sous-ensemble de photos sur, disons, chiens.

Mais si je veux ensuite continuer et récupérer une liste des photos de l'utilisateur? Comme il est possible que ces deux ensembles de données soient intersecteurs, devons-je effectuer une demande de récupération sur les données existantes, mettre à jour ce qui est déjà là, puis insérer les nouveaux objets?

-

Dans le modèle ancien, je disposerais simplement de structures de données distinctes pour chacun de ces ensembles de données et d'y accéder de manière appropriée. Un ensemble récentPhotos et et un ensemble d'utilisateursPhotos. Mais puisque le schéma général des données de base semble être d'utiliser un contexte d'objet géré, il semble que cela semble (je pourrais me tromper) que je dois fusionner mes données avec le pool principal de données. Mais cela semble être beaucoup de frais généraux juste pour attraper une liste de photos. Devrais-je créer un contexte d'objet géré séparé pour l'ensemble différent? Les données de base doivent-elles même être utilisées ici?

Je pense que ce que je trouve en appel quant aux données de base, c'est qu'avant (pour un service Web), je demanderais une demande de certaines données et de filtrer dans la demande ou de filtrer dans le code et produisez une liste que j'utiliserais. Avec des données de base, je peux simplement obtenir la liste d'objets, les ajouter à ma piscine (mise à jour des objets anciens si nécessaire), puis interroger contre elle. Un problème, je peux voir avec cette approche, cependant, est que si des objets sont supprimés de l'extérieur, je ne sais pas, car je garde mes anciennes données.

suis-je quelque chose de base ici? Existe-t-il des schémas que les personnes suivent pour traiter des données distantes et des données de base? :) J'ai trouvé quelques postes de gens disant qu'ils l'ont fait et que cela fonctionne pour eux, mais peu d'exemples. Merci.


2 commentaires

Pouvez-vous être plus précis sur ce que vous voulez? 'Utilise une source de données externe' est très vague. On dirait que vous souhaitez refléter une pièce de base de données externe localement. Avez-vous besoin de faire des changements locaux qui vous sont propulsés? Qu'en est-il des conflits? C'est un problème difficile et plus de détails aidera à suggérer des directions.


peut-être un fil rassis, je serais tenté d'essayer d'aller chercher des objets dans un fil d'antécédent et d'écrire dans le magasin persistant et d'avoir des notifications à la hauteur de là au fil principal - je ne serais pas bien sûr, mais si ça faisait


3 Réponses :


0
votes

Pour une situation comme celle-ci, vous pouvez utiliser les installations d'archivage du cacao pour enregistrer les objets photo (et un index) sur le disque entre les sessions et simplement écraser tout cela chaque fois que l'application appelle à la maison à Flickr.

Mais puisque vous utilisez déjà des données de base, et comme les fonctionnalités fournies, pourquoi ne pas modifier votre modèle de données pour inclure une attribute "Source" ou "CallType"? Pour le moment, vous créez implicitement un tas d'objets avec la source "API Flickr", mais vous pouvez aussi facilement traiter les différents appels d'API en tant que sources uniques, puis stocker cela explicitement.

Pour gérer la suppression, le moyen le plus simple serait d'effacer le magasin de données à chaque fois qu'il est rafraîchi. Sinon, vous auriez besoin de itérer tout et ne supprimez que les objets de photo avec des noms de fichiers qui n'étaient pas inclus dans les nouveaux résultats.

Je prévois de faire quelque chose de similaire à cela moi-même, j'espère que cela aide.

PS: Si vous ne stockez pas les objets photo entre les sessions, vous pouvez simplement utiliser deux contextes différents et les interroger séparément. Tant qu'ils ne sont jamais sauvés et que le magasin central n'en ait rien, cela fonctionnerait comme si vous décrivez.


0 commentaires

2
votes

Il me semble que votre premier instinct a raison: vous devez utiliser des fetchrequest pour mettre à jour votre magasin existant. L'approche que j'ai utilisée pour un importateur était la suivante: Obtenez une liste de tous les fichiers éligibles pour importer et stocker quelque part. Je suppose que ici que l'obtention de cette liste est rapide et légère (juste un nom et une URL et une carte d'identité unique), mais que cela importait vraiment quelque chose prendra un peu plus de temps et d'efforts et que l'utilisateur peut quitter le programme ou vouloir faire quelque chose sinon avant que toute l'importation soit terminée.

Ensuite, sur un thread de fond séparé (ce n'est pas aussi difficile que cela sonne grâce à Nsrunloop et Nstimer, Google sur "Données de base: importation efficace des données"), obtenez le premier élément de cette liste, obtenez l'objet de flickr Ou partout et recherchez-la dans la base de données de données de base (lire attentivement le guide de programmation du prédicat d'Apple sur la mise en place de Nsfetchrequest efficace, mise en cache de Nsfetchrequest). Si l'objet distant vit déjà dans des données de base, mettez à jour les informations nécessaires, sinon insérez. Une fois que cela est fait, supprimez l'élément de la liste des fichiers à être importés et passez à la suivante.

Quant au problème des objets supprimés dans le magasin distant, il existe deux solutions: synchronisation périodique ou synchronisation paresseux et paresseux. L'importation d'une photo de Flickr signifie-t-elle importer la chose originale et toutes ses métadonnées (je ne sais pas quelle est la politique concernant la propriété, etc.) Ou voulez-vous simplement importer une vignette et des informations? Si vous stockez tout localement, vous pouvez simplement exécuter un chèque tous les deux jours ou quelques semaines pour voir si tout dans votre magasin local est également présent à distance: sinon, l'utilisateur peut décider de garder la photo de toute façon ou de la supprimer. Si vous stockez uniquement les vignettes ou les aperçus, vous devez vous connecter à Flickr chaque fois que l'utilisateur souhaite voir la photo complète. S'il a été supprimé, vous pouvez ensuite informer l'utilisateur et la supprimer localement, ou la marquer comme n'étant plus accessible.


0 commentaires

3
votes

Vous pouvez essayer une combinaison de deux choses. Cette stratégie vous donnera une interface où vous obtenez les résultats d'un Nsfetchrequest à deux reprises: une fois de manière synchrone, et une fois à nouveau lorsque des données ont été chargées à partir du réseau.

  1. Créez votre propre sous-classe de nsfetchrequest qui prend une propriété de bloc supplémentaire pour exécuter quand la récupération est terminée. Ceci est pour votre asynchrone demande au réseau. Appelons Il flrfetchrequest

  2. Créer une classe à laquelle vous passez cette demande. Appelons ça flrphotomanager . flrphotomanager a une méthode exécuteurfetchrequest: qui prend un instance du flrfetchrequest et ...

    1. files d'attente Votre demande de réseau basée sur la demande de récupération et passe le long de la demande de récupération conservée à traiter à nouveau lorsque la demande de réseau est terminée.
    2. exécute la demande de récupération contre votre cache de Coredata et renvoie immédiatement les résultats.
    3. Maintenant, lorsque la demande de réseau se termine, mettez à jour votre cache de données de base avec les données réseau, exécutez la requête de récupération à nouveau sur le cache, et cette fois, tirez le bloc de la Flrfetchrequest et transmettez les résultats de cette demande de récupération dans le bloc. , complétant la deuxième phase.

      C'est le meilleur modèle que j'ai proposé, mais comme vous, je suis intéressé par les opinions d'autres.


1 commentaires

J'ai également proposé une approche similaire - je me demande si vous avez trouvé une meilleure façon de le faire maintenant?