2009-12-01 3 views
4

J'ai des problèmes avec l'implémentation de Core Data dans mon projet iPhone existant. D'abord, je veux vous donner une vue plus détaillée sur elle:Mise en œuvre de données de base pour un projet iPhone existant

  • Certains de mes classes sont imbriquées les unes aux autres: La classe « Game » a un NSArray avec des objets de la classe « Player », la classe « joueur » a un NSArray avec des objets de la classe "Item" à son tour. Ce que je veux faire est d'enregistrer une instance de mon "jeu" classe "Jeu" (par exemple en quittant mon application).

J'ai essayé quelques tutoriels sur base de données, mais il y a encore quelques questions:

  1. Dois-je créer une entité pour chacun de mes cours ou tout simplement pour « Game »?
  2. Si je dois le faire pour chacun: Je pense que je vais devoir créer TOUTES les relations entre mes classes, mais: Comment créer les relations, par ex. entre "Game" et "Player" (rappelez-vous: je possède BEAUCOUP de joueurs dans ONE NSArray) ..
  3. Qu'en est-il de changer mon projet existant? Ce que j'ai déjà fait est de copier les méthodes manquantes dans mon AppDelegate. Mais qu'est-ce que je vais faire avec mes cours, surtout avec les méthodes Getter/Setter? Changez simplement "@synthesize" en "@dynamic" dans l'implémentation?

J'espère un peu de lumière dans mon obscurité;)

Merci beaucoup en ce moment

Mac1988

Répondre

2

Ce que je recommande est de configurer votre modèle de base de données dans Xcode, lorsque vous avez fait cela ... choisissez les entités et choisissez dans le menu Fichier> Nouveau fichier. Choisissez ensuite la "Classe d'objets gérés" de la "Classe tactile Cocoa". Après "Suivant" choisissez où sauvegarder les fichiers, et à l'étape suivante, XCode vous demandera quelles entités doivent être générées dans les fichiers.

Après avoir fait cela, vous pouvez implémenter les fonctions dont vous avez besoin dans votre ex. vous déléguez. Ma recommandation est de laisser vos choses existantes telles quelles et d'utiliser les classes de données de base comme étant les leurs. Retirez simplement les données dont vous avez besoin de vos classes/tableaux existants et placez-les dans la base de données selon vos besoins. Lors de la récupération, dans l'autre sens ... récupérez-les dans la base de données et ajoutez-les à vos fonctions/classes.

Exemple d'un de mes projets:

Le fichier .h

@class quicklistSet; 

@interface rankedAppDelegate : NSObject <UIApplicationDelegate, UITabBarControllerDelegate> { 
[...] 

    NSMutableArray *_searchHistory; 
    NSMutableArray *_quickList; 
} 

[...] 

@property (nonatomic, retain) NSMutableArray *_searchHistory; 
@property (nonatomic, retain) NSMutableArray *_quickList; 

/* Quicklist functions */ 
- (void)addToQuicklist:(quicklistSet *)theQuicklistSet; 
- (BOOL)checkIfQuicklistExists:(quicklistSet*)theQuicklistSet; 
- (NSMutableArray *)getQuicklists; 
- (void)deleteQuicklist:(NSNumber*)theAppId; 


@end 

Le fichier .m

#import "quicklistSet.h" 
#import "quicklist.h" 

@implementation rankedAppDelegate 

@synthesize window; 
@synthesize tabBarController; 
@synthesize _searchHistory, _quickList; 

[...] 

/* Quicklist functions */ 
- (void)addToQuicklist:(quicklistSet *)theQuicklistSet 
{ 
    BOOL exists = [self checkIfQuicklistExists:theQuicklistSet]; 

    if(!exists) 
    { 
     quicklist *theQuicklist = (quicklist *)[NSEntityDescription insertNewObjectForEntityForName:@"quicklist" 
                         inManagedObjectContext:self.managedObjectContext]; 

     [theQuicklist setAppName:[theQuicklistSet _appName]]; 
     [theQuicklist setAppId:[theQuicklistSet _appId]]; 
     [theQuicklist setAppImage:[theQuicklistSet _appImage]]; 
     [theQuicklist setCountryId:[theQuicklistSet _countryId]]; 
     [theQuicklist setCategoryId:[theQuicklistSet _categoryId]]; 
     [theQuicklist setLastCheck:[theQuicklistSet _lastCheck]]; 
     [theQuicklist setLastRank:[theQuicklistSet _lastRank]]; 

     [_quickList addObject:theQuicklist]; 

     [self saveAction]; 
    } 
    else { 
     NSLog(@"Existing quicklistSet: %@", [theQuicklistSet _appName]); 
    } 
} 

- (BOOL)checkIfQuicklistExists:(quicklistSet*)theQuicklistSet 
{ 
    // Get the categories 
    NSMutableArray *quicklistArray = [self getQuicklists]; 

    BOOL exists = NO; 

    for(quicklist *dbQuicklist in quicklistArray) 
    { 
     if([[dbQuicklist appId] isEqualToNumber:[theQuicklistSet _appId]]) 
     { 
      exists = YES; 
      continue; 
     } 
    } 

    return exists; 
} 

- (NSMutableArray *)getQuicklists 
{ 
    if(_quickList == NULL) 
    { 
     NSLog(@"Array is null"); 

     NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; 

     NSEntityDescription *entity = [NSEntityDescription entityForName:@"quicklist" 
                inManagedObjectContext:self.managedObjectContext]; 
     [fetchRequest setEntity:entity]; 

     NSError *error; 
     NSArray *items = [[self.managedObjectContext 
          executeFetchRequest:fetchRequest error:&error] retain]; 

     NSMutableArray *returnArray = [[[NSMutableArray alloc] initWithArray:items] retain]; 

     _quickList = returnArray; 

     [fetchRequest release]; 
    } 
    else { 
     NSLog(@"Not null. Count: %d", [_quickList count]); 
    } 

    return _quickList; 
} 

- (void)deleteQuicklist:(NSNumber*)theAppId 
{ 
    NSLog(@"Delete row"); 

    // Create a new managed object context for the new book -- set its persistent store coordinator to the same as that from the fetched results controller's context. 
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; 
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"quicklist" 
               inManagedObjectContext:self.managedObjectContext]; 

    [fetchRequest setEntity:entity]; 
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"appId=%@",theAppId]; 
    [fetchRequest setPredicate:predicate]; 

    NSError *error; 
    NSArray *items = [self.managedObjectContext 
         executeFetchRequest:fetchRequest error:&error]; 
    [fetchRequest release]; 

    if([items count] > 0) 
    { 
     NSManagedObject *eventToDelete = [items objectAtIndex:0]; 
     [self.managedObjectContext deleteObject:eventToDelete]; 

     [self saveAction]; 
    } 
} 
/* END Quciklist functions */ 

[...] 

@end 

EDIT: Le quicklistSet était ma classe existsing, le Pense-bête est ma classe de coredata.

+0

Bonjour Paul, merci pour votre réponse et votre exemple. Qu'est-ce que vous voulez dire est de créer une nouvelle classe "GameData" qui est géré par Core Data, et tirer et enregistrer mes objets "à partir de là", non? Ce que je ne comprenais toujours pas, c'est comment créer l'entité: par ex. un attribut "Player" et une relation "to-many" à ma classe "Player" existante? Ou devrais-je créer une nouvelle classe "Player"? Ou est-ce tout terrible mal? ;) – Mac1988

+0

Je comprends ce que vous voulez dire, mais je ne peux pas vous donner une réponse directe à ce sujet. Je suis trop inexpérimenté avec core-data pour le moment. Ce que je sais, c'est que de chaque entité, les données de base créent une classe avec des valeurs dynamiques. Vous pouvez également définir des relations les uns avec les autres, mais vous ajoutez simplement une autre classe à l'entité. Je pense que vous devrez également créer une nouvelle classe de joueurs, mais peut-être que quelqu'un ayant plus d'expérience pourrait mieux répondre à votre question. Bonne chance! –

1
  1. Oui, vous souhaitez créer une entité pour toutes les classes que vous avez mentionnées.

  2. Vous avez déjà la réponse à cette question dans votre question: établissez une relation un-à-plusieurs.Par exemple, pour la relation joueurs de Game, cliquez sur la case à cocher "To-many relationship" dans l'éditeur de modèle de données.

  3. Vous voulez que vos classes de données (Game, Player, Item) héritent de NSManagedObject. Vous souhaiterez probablement supprimer toutes les variables d'instance correspondant aux attributs que vous avez ajoutés dans les données de base. Pour les relations to-many (players, items), vous voudrez certainement vous débarrasser de la variable membre de NSArray que vous utilisiez. Au lieu de cela, faites comme vous disiez et créez des accesseurs @dynamic pour les propriétés des joueurs et des objets. Notez que vous souhaitez utiliser un NSSet au lieu d'un NSArray pour les lecteurs et les éléments.

Par exemple, l'en-tête de votre classe de jeu pourrait ressembler à ceci:

@interface Game : NSManagedObject { 

} 

@property(nonatomic, retain) NSSet *players 
@property(nonatomic, retain) NSString *someOtherProperty; 
@property(nonatomic, retain) NSNumber *yetAnotherProperty; 

@end 

Et puis votre fichier de mise en œuvre pourrait ressembler à:

#import "Game.h" 

@implementation Game 

@dynamic players, someOtherProperty, yetAnotherProperty; 

- (void)awakeFromInsert { 
    // do initialization here 
} 

// other methods go here 

@end 

Aussi, soyez prudent lors de la modification les propriétés des joueurs et des objets. La section Using Managed Objects du guide de programmation des données de base a beaucoup de bons détails, mais essentiellement pour ajouter un joueur à une instance de jeu, vous feriez

[game addPlayerObject:newPlayer]; 

Pour créer réellement le nouveau joueur, vous feriez quelque chose comme:

NSManagedObject *newPlayer = [NSEntityDescription insertNewObjectForEntityForName:@"Player" inManagedObjectContext:context]; 
Questions connexes