внедрение базовых данных в существующий iPhone-проект - PullRequest
4 голосов
/ 01 декабря 2009

У меня возникли проблемы с внедрением Core Data в мой существующий iPhone-проект. Сначала я хочу дать вам более подробный обзор:

  • Некоторые из моих классов вложены друг в друга: класс «Game» имеет NSArray с объектами класса «Player», класс «Player» имеет NSArray с объектами класса «Item» по очереди.

  • То, что я хочу сделать, - это сохранить экземпляр моего «самого грубого» класса «Игра» (например, при выходе из моего приложения).

Я опробовал несколько учебных пособий по основным данным, но есть еще вопросы:

  1. Нужно ли создавать сущность для каждого из моих классов или только для «Игры»?
  2. Если я должен сделать это для каждого: я думаю, что мне нужно будет создать ВСЕ отношения между моими классами, но: Как создать отношения, например, между «Игрой» и «Игроком» (напомните: я держу МНОГИХ игроков в ОДНОМ NSArray) ..
  3. А как насчет изменения моего существующего проекта? Я уже скопировал недостающие методы в мой AppDelegate. Но что мне делать с моими классами, особенно с методами Getter / Setter? Просто измените "@synthesize" на "@dynamic" в реализации?

Я надеюсь на свет в моей темноте;)

Большое спасибо прямо сейчас

Mac1988

Ответы [ 2 ]

2 голосов
/ 01 декабря 2009

Я рекомендую настроить модель базы данных в xcode, а затем, когда вы это сделаете ... выберите объекты и выберите в меню Файл> Новый файл. Затем выберите «Класс управляемых объектов» из «Класса касания Какао». После «Далее» выберите место для сохранения файлов, и на следующем шаге XCode спросит вас, какие объекты должны быть сгенерированы в файлы.

После того, как вы это сделаете, вы можете реализовать нужные функции в своем примере. Вы делегируете. Я рекомендую оставить все как есть и использовать основные классы данных как свои собственные. Просто извлеките нужные данные из существующих классов / массивов и поместите их в базу данных по мере необходимости. При извлечении, наоборот ... получите их из БД и добавьте в свои функции / классы.

Пример из одного из моих проектов:

.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

.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: QuicklistSet был моим существующим классом, quicklist - моим классом coredata.

1 голос
/ 06 декабря 2009
  1. Да, вы хотите создать сущность для всех упомянутых вами классов.

  2. У вас уже есть ответ на этот вопрос: установите отношения один ко многим. Например, для отношений игроков в игре установите флажок «Отношение ко многим» в редакторе модели данных.

  3. Вы хотите, чтобы ваши классы данных (Game, Player, Item) наследовались от NSManagedObject. Возможно, вы захотите удалить все переменные экземпляра, которые соответствуют атрибутам, которые вы добавили в Core Data. Для отношений ко-многим (игроки, предметы) вы определенно захотите избавиться от используемой вами переменной-члена NSArray. Вместо этого, делайте то, что вы сказали, и создавайте средства доступа @dynamic для свойств игроков и предметов. Обратите внимание, что вы хотите использовать NSSet вместо NSArray для игроков и предметов.

Например, заголовок для вашего класса Game может выглядеть так:

@interface Game : NSManagedObject {

}

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

@end

И тогда ваш файл реализации может выглядеть так:

#import "Game.h"

@implementation Game

@dynamic players, someOtherProperty, yetAnotherProperty;

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

// other methods go here

@end

Также будьте осторожны при изменении свойств игроков и предметов. Раздел Использование управляемых объектов в Руководстве по программированию основных данных содержит много полезных деталей, но в основном для добавления Player в экземпляр Game вы должны сделать

[game addPlayerObject:newPlayer];

Чтобы создать нового игрока, вы должны сделать что-то вроде:

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