2

アプリの reousrce-folder に入力済みの sqlite データベースがあります。起動時に、この sqlite db のデータを coredata-store にプリロードしたいと思います。persistantStoreCoordinator メソッドで NSMigrationManager を使用します。これは最初はうまく機能し、データをストアに追加します。ただし、起動するたびにデータが再度追加されるため、2 回目の起動後にデータが複製されます。どうすればこれを解決できますか? データベースでは主キーを使用しますが、データ モデルに似たものはありますか? または、エンティティ オブジェクトを比較できますか?

私が使用する方法の下で、あなたの助けに感謝します:

- (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_;
}
4

1 に答える 1

2

提供されているコードは、デフォルトのファイルがドキュメントフォルダーにある場合はそれをマージします。マージ後にファイルを削除した場合、毎回ロードされるわけではありません。以前にマージされていた場合は、ユーザーのデフォルトフラグを設定して記録することができます。

より良い解決策は、デフォルトのデータを使用してCore Data永続ストアを作成し、それをアプリバンドルに含めることです。最初の起動時に、そのファイルをドキュメントフォルダーにコピーし、永続ストアに割り当てるだけです。その方法はより高速であり、マージが失敗することを心配する必要はありません。

于 2010-12-05T15:46:25.917 に答える