我的应用包含2个数据库:
如果我使用2 MOC和2 PSC(每个数据库一个)初始化Core Data:一切正常。但是我想为这两个数据库初始化只有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,但Core Data不会将其识别为此数据库的基本模型...
连连呢?
答案 0 :(得分:0)
这种情况正在发生,因为您最初使用其中一个数据库在手机中安装了该应用。现在您已添加/更改了数据库。所以它无法识别新的数据库。因为应用程序最初是使用不同的数据库创建/安装的。
尝试从手机中删除该应用并重新安装。错误将会发生。
希望这会有所帮助。 :)
答案 1 :(得分:0)
我找到了解决这个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]);
});
}
我们必须:
如果有人能解释我为什么这个配置有效...因为我真的不明白这一点。