2016-05-19 11 views
2

私のアプリは2つのデータベースが含まれます。コアデータ:店を開くために使用されるモデルは、ストアを作成するために使用したものと互換性がありません

  • DB1:読み取り/書き込みデータベース(すべてのユーザー設定を保存する)を
  • DB2:読み取り専用データベース、別のプロジェクトにプリロード(Iプロジェクトで.sqlite、.xcdatamodeldおよびエンティティクラスをコピー)

iが2 MOC及び2 PSCとコアデータを初期化する場合(各データベースに対して1つの):すべて正常に動作します。しかし、私は2つのデータベースのための1つのMOC/PSCを初期化したいと思います。これを行うために、私は次のコードを書いた:

- (NSManagedObjectContext *)managedObjectContext 
{ 
    if (_managedObjectContext != nil) { 
     return _managedObjectContext; 
    } 

    NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator]; 
    if (coordinator != nil) { 
     _managedObjectContext = [[NSManagedObjectContext alloc] init]; 
     [_managedObjectContext setPersistentStoreCoordinator:coordinator]; 
    } 
    return _managedObjectContext; 
} 
- (NSManagedObjectModel *)managedObjectModel 
{ 
    if (_managedObjectModel != nil) { 
     return _managedObjectModel; 
    } 
    NSURL *db1ModelURL = [[NSBundle mainBundle] URLForResource:@"db1" withExtension:@"momd"]; 
    NSManagedObjectModel *db1Mom = [[NSManagedObjectModel alloc] initWithContentsOfURL:db1ModelURL]; 
    NSURL *db2ModelURL = [[NSBundle mainBundle] URLForResource:@"db2" withExtension:@"momd"]; 
    NSManagedObjectModel *db2Mom = [[NSManagedObjectModel alloc] initWithContentsOfURL:db2ModelURL]; 
    NSAssert(db1 != nil, @"Error initializing Managed Object Model"); 
    NSAssert(db2 != nil, @"Error initializing Managed Object Model"); 

    _managedObjectModel=[NSManagedObjectModel modelByMergingModels:[NSArray db1Mom,db2Mom, nil]]; 

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

    NSURL * db1URL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"db1.sqlite"]; 

    NSURL *db2URL = [[NSBundle mainBundle] URLForResource:@"db2" withExtension:@"sqlite"]; 

    NSError *error = nil; 
    _persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]]; 

    _persistentStoreCoordinator = [[self managedObjectContext] persistentStoreCoordinator]; 
    NSMutableDictionary * db2Options=[NSMutableDictionary dictionaryWithObjectsAndKeys: 
             @YES,NSReadOnlyPersistentStoreOption, 
             nil]; 
    NSPersistentStore *store = [_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:@"DB2" URL:db2URL options:db2Options error:&error]; 
    NSAssert(store != nil, @"Error initializing PSC: %@\n%@", [error localizedDescription], [error userInfo]); 

    NSMutableDictionary * db1Options=[NSMutableDictionary dictionaryWithObjectsAndKeys: 
             @YES,NSMigratePersistentStoresAutomaticallyOption, 
             @YES,NSInferMappingModelAutomaticallyOption, 
             nil]; 
    store = [_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:@"DB1" URL:db1URL options:db1Options error:&error]; 
    NSAssert(store != nil, @"Error initializing PSC: %@\n%@", [error localizedDescription], [error userInfo]); 

    return _persistentStoreCoordinator; 
} 

を、私はアプリを起動したときに、私は、DB2データベースに次のエラーを取得:

The model used to open the store is incompatible with the one used to create the store 

私は問題がへの呼び出しが付属して考えますmodelByMergingModels、結果のモデルにはdb2Modelが含まれていますが、コア・データはそれをこのデータベースのベース・モデルとして認識しません。

提案はありますか?

+1

アプリを一度削除してインストールしてみてください。 – vaibhav

+0

コアデータに変更を加えたら、アプリを削除してから再インストールする必要があります。 – Starlord

+0

@Joakim私はすでにアプリを削除/インストールしようとしましたが動作しません。私はこのエラーが新しくインストールされた後に発生しています... –

答えて

1

私はこれを読んで解決策を見つけたarticle。それが動作する理由私は...

- (void)initializeCoreData{ 
// Initialize models 
NSURL *db2ModelURL = [[NSBundle mainBundle] URLForResource:@"villes" withExtension:@"momd"]; 
NSManagedObjectModel *db2Mom = [[NSManagedObjectModel alloc] initWithContentsOfURL:db2ModelURL]; 
NSAssert(db2Mom != nil, @"Error initializing Managed Object Model"); 

NSURL *db1ModelURL = [[NSBundle mainBundle] URLForResource:@"MMAMeteoPro" withExtension:@"momd"]; 
NSManagedObjectModel *db1Mom = [[NSManagedObjectModel alloc] initWithContentsOfURL:db1ModelURL]; 
NSAssert(db1Mom != nil, @"Error initializing Managed Object Model"); 


NSManagedObjectModel * fullModel=[NSManagedObjectModel modelByMergingModels:[NSArray arrayWithObjects:db1Mom,db2Mom, nil]]; 

// Initialize context 
NSPersistentStoreCoordinator *psc = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:fullModel]; 
NSManagedObjectContext *moc = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType]; 
[moc setPersistentStoreCoordinator:psc]; 
[self setManagedObjectContext:moc]; 

// Initialize stores 
NSURL *db2StoreURL = [[NSBundle mainBundle] URLForResource:@"db2" withExtension:@"sqlite"]; 
NSFileManager *fileManager = [NSFileManager defaultManager]; 
NSURL *documentsURL = [[fileManager URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject]; 
NSURL *db1StoreURL = [documentsURL URLByAppendingPathComponent:@"db1.sqlite"]; 

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void) { 
    NSError *error = nil; 
    NSPersistentStoreCoordinator *psc = [[self managedObjectContext] persistentStoreCoordinator]; 
    NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys: 
          [NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption, 
          [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, 
          nil]; 
    NSMutableDictionary * db2Options=[NSMutableDictionary dictionaryWithObjectsAndKeys: 
            @{@"journal_mode":@"DELETE"},NSSQLitePragmasOption, 
            @YES, NSReadOnlyPersistentStoreOption, 
            nil]; 
    NSMutableDictionary * db1Options=[NSMutableDictionary dictionaryWithObjectsAndKeys: 
             @{@"journal_mode":@"DELETE"},NSSQLitePragmasOption, 
             nil]; 
    NSPersistentStore * tempStore = [psc addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:db2StoreURL options:options error:&error]; 
    NSAssert(error == nil, @"Error initializing PSC: %@\n%@", [error localizedDescription], [error userInfo]); 
    [psc removePersistentStore:tempStore error:&error]; 
    NSAssert(error == nil, @"Error initializing PSC: %@\n%@", [error localizedDescription], [error userInfo]); 
    tempStore=[psc addPersistentStoreWithType:NSSQLiteStoreType configuration:@"DB2Conf" URL:villeStoreURL options:db2Options error:&error]; 
    NSAssert(error == nil, @"Error initializing PSC: %@\n%@", [error localizedDescription], [error userInfo]); 
    tempStore=[psc addPersistentStoreWithType:NSSQLiteStoreType configuration:@"DB1Conf" URL:meteoStoreURL options:db1Options error:&error]; 
    NSAssert(error == nil, @"Error initializing PSC: %@\n%@", [error localizedDescription], [error userInfo]); 
}); 

}

を理解していない場合でも、我々はする必要があります。

  1. の軽量移行オプションで、最初の読み取り専用永続ストアを追加し、 ReadOnlyオプションも構成もありません
  2. この永続ストアを削除しますか?
  3. 今回は軽量な移行オプションを使用せずに、ReadOnly a良い設定をしてください。
  4. この設定が機能する理由を誰かが私を説明することができた場合は

に永続ストアを書いてください...私は本当にここでのポイントを取得しない原因/読み取りを追加します。

0

最初にdbのいずれかを使用してアプリを携帯電話にインストールしたために起こっています。 DBを追加/変更しました。したがって、新しいDBは認識されません。アプリはもともとは別のDBを使用して作成/インストールされていたためです。

携帯電話からアプリを削除してもう一度インストールしてみてください。エラーが発生します。

これが役に立ちます。 :)

関連する問題