Ручная миграция CoreData с NSMigrationManager для добавления данных (предварительная загрузка) - PullRequest
2 голосов
/ 05 декабря 2010

В моей reousrce-папке приложения есть заполненная база данных sqlite. При запуске я хочу предварительно загрузить coredata-store с данными этой базы данных sqlite. Я использую NSMigrationManager в методе persistantStoreCoordinator. Это отлично работает в первый раз и добавит данные в магазин. Но он будет добавлять данные при каждом запуске снова, поэтому данные будут дублироваться после второго запуска. Как я могу решить это? В базе данных я бы использовал первичные ключи, есть ли что-то похожее в модели данных? Или я могу сравнить сущности-объекты?

Спасибо четыре за вашу помощь, ниже метод, который я использую:

- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {
 if (persistentStoreCoordinator_ != nil) {
  return persistentStoreCoordinator_;
 }

 NSString *storePath = [[self applicationDocumentsDirectory] stringByAppendingPathComponent:@"Raetselspass.sqlite"];
 NSURL *storeUrl = [NSURL fileURLWithPath:storePath];
 NSString *defaultStorePath = [[NSBundle mainBundle] pathForResource:@"Raetselspass" ofType:@"sqlite"];
 NSURL *defaultStoreUrl = [NSURL fileURLWithPath:defaultStorePath];

 /*
  Set up the store.
  For the sake of illustration, provide a pre-populated default store.
  */
        // CANNOT USE THIS BELOW: WILL WORK ONCE, BUT WHEN I WILL UPDATE THE APP WITH
        // NEW DATA TO APPEND, THEN THIS WILL NOT WORK
 // NSFileManager *fileManager = [NSFileManager defaultManager];
 // If the expected store doesn’t exist, copy the default store.
 // if (![fileManager fileExistsAtPath:storePath]) {
 //  if (defaultStorePath) {
 //   [fileManager copyItemAtPath:defaultStorePath toPath:storePath error:NULL];
 //  }
 // }

 NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption, [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];
 persistentStoreCoordinator_ = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel: [self managedObjectModel]];

 NSError *error;
 if (![persistentStoreCoordinator_ addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrl options:options error:&error]) {
  // Update to handle the error appropriately.
  NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
  abort();  // Fail
 }

 //migration
rror:&error];
 NSError *err = nil;
 NSMigrationManager *migrator = [[NSMigrationManager alloc] initWithSourceModel:[self managedObjectModel] destinationModel:[self managedObjectModel]];
 NSMappingModel *mappingModel = [NSMappingModel inferredMappingModelForSourceModel:[self managedObjectModel] destinationModel:[self managedObjectModel] error:&err];
 NSError *err2;
 if (![migrator migrateStoreFromURL:defaultStoreUrl 
          type:NSSQLiteStoreType 
          options:nil 
       withMappingModel:mappingModel 
       toDestinationURL:storeUrl 
        destinationType:NSSQLiteStoreType 
     destinationOptions:nil 
         error:&err2])
 {
  //handle the error
 }
 NSLog(@"import finished");
 [migrator release];

 return persistentStoreCoordinator_;
}

1 Ответ

2 голосов
/ 05 декабря 2010

Приведенный код объединит файл по умолчанию, если он присутствует в папке документов. Если вы удалите файл после слияния, он не должен загружаться каждый раз. Вы можете установить флаг пользователя по умолчанию для записи, если он был ранее объединен.

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

...