43 votes

données de base dans une bibliothèque statique pour l'iPhone

J'ai construit une bibliothèque statique qui fait un usage intensif de la Base de Données de cadre. Je peux utiliser avec succès la bibliothèque dans mon projet externe, mais SEULEMENT si je comprend l' .fichier xcdatamodel dans le projet principal. C'est pas l'idéal, car le point de la bibliothèque est de cacher les détails d'implémentation du maximum possible.

Dans une autre question, j'ai été informé que je ne peux pas le bundle de ressources de la bibliothèque (qui prend tout son sens pour moi maintenant).

Donc, il y a un moyen d'en programmant permettre au modèle d'être "découvert" sans avoir à inclure le modèle dans le projet principal?

59voto

Prairiedogg Points 3594

Sascha réponse m'a mis sur la bonne voie. La fusion d'un compilé .mom le fichier à partir d'une bibliothèque statique dans l' .mom le fichier à partir d'un hôte projet a été relativement simple. Voici un exemple trivial:

  1. Créer un nouveau XCode Bibliothèque Statique projet appelé" MyStaticLibrary

  2. Créer un .fichier xcdatamodel en MyStaticLibrary appelés MyStaticLibraryModels.xcdatamodel, ajouter un peu d' Entitys, puis de générer les en-têtes et des implémentations. Lorsque vous générez l' MyStaticLibrary de la cible, vous allez générer un libMyStaticLibrary.a le fichier binaire, mais il ne comprend pas le compilé .mom le fichier. Pour cela, nous devons créer un bundle.

  3. Construire une nouvelle cible de type Loadable Bundlesous MacOS X > Cocoa, appelons la nouvelle Cible MyStaticLibraryModels.

  4. Faites glisser MyStaticLibraryModels.xcdatamodel dans la Compile Sources phase de construction de l' MyStaticLibraryModels de la Cible. Lorsque vous générez l' MyStaticLibraryModels de la Cible, vous allez générer un fichier appelé MyStaticLibraryModels.bundle et il contiendra l'compilé NSManagedObjectModel fichier MyStaticLibraryModels.mom.

  5. Après la construction du bâtiment à la fois l' MyStaticLibrary et MyStaticLibraryModels Cibles, faites glisser libMyStaticLibrary.a (avec Modèle associé fichiers d'en-tête) et MyStaticLibraryModels.bundle dans votre projet hôte, MyAwesomeApp.

  6. MyAwesomeApp utilise CoreData, a sa propre .xcdatamodel le fichier qui sera compilé dans un .maman de fichier lors de son propre processus de construction. Nous voulons fusionner ce .mom le fichier avec celui que nous importés en MyStaticLibraryModels.bundle. Quelque part dans l' MyAwesomeApp du projet, il y a une méthode qui retourne MyAwesomeApps NSManagedObjectModel. L'Apple modèle généré par cette méthode ressemble à ceci:

...

- (NSManagedObjectModel *)managedObjectModel {
  if (managedObjectModel_ != nil) {
    return managedObjectModel_;
  }
  NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"MyAwesomeApp" withExtension:@"momd"];
  managedObjectModel_ = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];    
  return managedObjectModel_;
}

Nous allons modifier ce de fusionner et de retour à la FOIS de notre - NSManagedObjectModels, MyAwesomApps et MyStaticLibraryModels, comme un seul, combinés NSManagedObjectModel comme:

- (NSManagedObjectModel *)managedObjectModel {
  if (managedObjectModel_ != nil) {
    return managedObjectModel_;
  }

  NSMutableArray *allManagedObjectModels = [[NSMutableArray alloc] init];

  NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"MyAwesomeApp" withExtension:@"momd"];
  NSManagedObjectModel *projectManagedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
  [allManagedObjectModels addObject:projectManagedObjectModel];
  [projectManagedObjectModel release];

  NSString *staticLibraryBundlePath = [[NSBundle mainBundle] pathForResource:@"MyStaticLibraryModels" ofType:@"bundle"];
  NSURL *staticLibraryMOMURL = [[NSBundle bundleWithPath:staticLibraryBundlePath] URLForResource:@"MyStaticLibraryModels" withExtension:@"mom"];
  NSManagedObjectModel *staticLibraryMOM = [[NSManagedObjectModel alloc] initWithContentsOfURL:staticLibraryMOMURL];
  [allManagedObjectModels addObject:staticLibraryMOM];
  [staticLibraryMOM release];

  managedObjectModel_ = [NSManagedObjectModel modelByMergingModels:allManagedObjectModels];
  [allManagedObjectModels release];

  return managedObjectModel_;
}

Ce sera le retour de la fusionnées NSManagedObjectModel avec l' Entitys à partir de deux MyAwesomeApp et MyStaticLibrary.

31voto

Sascha Konietzke Points 897

J'ai également créé ma propre bibliothèque statique qui utilise la Base de Données. Outre les bibliothèque statique, j'ai un autre bundle cible dans le projet où j'ai une Copie de Bundle de Ressources élément, que des copies des images et des choses comme ça dans le bundle et la Compilation des Sources phase de construction, où je suis la compilation de la xcdatamodel.

Le dernier bundle contiendra tous les fichiers nécessaires. Dans votre projet principal, qui s'appuie sur la bibliothèque statique, vous devez inclure regrouper ainsi. Le principal de votre projet auront désormais accès à la maman de fichier qui est nécessaire pour l'utilisation de base de données.

Pour utiliser la base de données avec la maman du bundle, vous devez créer une fusion de modèle d'objet managé dans votre code (c'est peut être le principal projet dispose de quelques données de base modèle en tant que bien):


- (NSManagedObjectModel *) mergedManagedObjectModel 
{   
    if (!mergedManagedObjectModel) 
    {
    	NSMutableSet *allBundles = [[[NSMutableSet alloc] init] autorelease];
    	[allBundles addObjectsFromArray: [NSBundle allBundles]];
    	[allBundles addObjectsFromArray: [NSBundle allFrameworks]];

    	mergedManagedObjectModel = [[NSManagedObjectModel mergedModelFromBundles: [allBundles allObjects]] retain];
    }

    return mergedManagedObjectModel;
}


Par juste, y compris le bundle, vous n'aurez pas à donner le xcdatamodel, seul le compilé maman fichier doit être inclus.

2voto

Pixman Points 376

J'ai aussi une bibliothèque avec coredata. j'ai trouvé ce modèle pour gérer un cadre avec des ressources intégrées

c'est vraiment simple à utiliser sur un nouveau projet (plus difficile à appliquer sur des projets existants) mais pour les buildwoks, c'est vraiment cool :-)

https://github.com/kstenerud/iOS-Universal-Framework

2voto

Spanner Points 122

La solution de Sascha Konietzke fonctionne bien, mais une mise en garde importante doit être fournie pour que cela fonctionne. Le groupe contenant le modèle doit être chargé en premier, sinon il ne sera pas inclus dans le tableau et fusionné dans le MOM.

Dans son cas, il a probablement déjà déjà accédé à des ressources à partir du bundle; par conséquent, le bundle avait déjà été chargé avant l'exécution de ce code.

1voto

Barry Wark Points 73462

Non, la limitation sur l'utilisation de la non-Apple cadres dans une application iPhone qui change vraiment la dépendance de jeu par rapport à OS X. la Plupart des iPhone "cadres" (par exemple, Google toolbox for Mac, Cœur de l'Intrigue, etc.) en fait recommandons que vous comprendre la source de votre application principale du projet, plutôt que de lier un produit (par exemple, une bibliothèque statique). Je pense que le consensus de la communauté, c'est que, sur iPhone, c'est OK pour attendre des consommateurs de votre cadre pour faire un peu de "manuel" de travail pour l'utilisation de votre bibliothèque. Dans votre cas, c'est notamment le fichier xcdatamodel dans le projet principal. Comme avec la plupart de l'Objective-C, indiquez à vos utilisateurs de ne pas utiliser les détails de mise en œuvre et d'en rester là.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X