Найти или создать уникальный объект Core Data - PullRequest
13 голосов
/ 12 февраля 2011

Распространенным сценарием для основных приложений, управляемых данными, является получение уникального объекта из резервного хранилища.Если объект с определенным уникальным свойством существует, вернуть его, если он не возвращает вновь созданный.Я обнаружил, что пишу одно и то же снова и снова, поэтому обернул это удобным способом.Но это кажется таким тривиальным, я изобретаю колесо здесь?Есть ли более простой, готовый способ добиться этого?

Cheers,
EP

+(id)uniqueEntityfForName:(NSString *)name 
                withValue:(id)value 
                   forKey:(NSString *)key
   inManagedObjectContext:(NSManagedObjectContext *)context {

    NSFetchRequest *request = [[[NSFetchRequest alloc] init] autorelease];    
    request.entity = [NSEntityDescription entityForName:name inManagedObjectContext:context];
    request.predicate = [NSPredicate predicateWithFormat:[key stringByAppendingString:@" == %@"], value];
    NSArray *result = [context executeFetchRequest:request error:nil];

    id entity = [result lastObject];
    if (entity == nil) {
        entity = [NSEntityDescription insertNewObjectForEntityForName:name inManagedObjectContext:context];
        [entity setValue:value forKey:key];
    } else {
        entity = [result lastObject];
    }

    return entity;
}

Я использую этот метод следующим образом:

SomeEntity *entity = [CDUtils uniqueEntityfForName:@"SomeEntity" withValue:@"foo" forKey:@"bar" inManagedObjectContext:context];

Ответы [ 2 ]

3 голосов
/ 18 февраля 2011

Довольно стандартно.Мои основные объекты данных имеют множество методов, таких как [aStudent enrollmentForId:(long long)idValue createIfMissing:YES].

. Я также хотел бы подключить mogenerator , который устраняет большую часть проблем с Core Data.Помимо прочего, он генерирует фабричный метод для каждого запроса выборки, определенного в модели данных.Таким образом, создание предиката выборки в модели, например,

thingies: thingyId == $forThingyId

, дает метод соответствующего класса:

+(NSArray *)fetchThingies:(NSManagedObjectContext *)moc forThingyId:(id)thingyId

... что делает первую половину того, что вы там написали.В таком случае обертку наподобие

-(Thingy*)thingyForIdValue:(long long)thingyId

написать тривиально, в любом классе, содержащем ваш managedObjectContext (например, «родительский» объект, или делегат приложения, или любой другой.)

2 голосов
/ 27 декабря 2011

Более гибкое решение заключается в использовании Blocks, чтобы позволить вызывающей стороне обрабатывать 3 ситуации при сравнении двух списков.

  1. Соответствующие наборы
  2. Хост непревзойденные наборы
  3. Локальные несопоставленные наборы

Следовательно, нет необходимости создавать аналогичные функции при вставке в синхронизирующем режиме или добавлениях в хранилище данных.

typedef void (^objectOperationBlock)(NSManagedObjectContext *context,
                                 NSDictionary *hostObjectData,
                                 NSManagedObject *localManagedObject);

- (void) insertUniquely:(NSArray *)rawDataArray 
                 entity:(NSString *)entity 
           matchedBlock:(objectOperationBlock)matchedOperation
     hostUnmatchedBlock:(objectOperationBlock)hostUnmatchedOperation
    localUnmatchedBlock:(objectOperationBlock)localUnmatchedOperation
                  error:(NSError **)outError;

Полная реализация может быть найдена здесь: http://emplementation.blogspot.com/2011/12/importing-data-into-core-data-while.html

...