确定核心数据模型中何时存在新版本

时间:2012-10-06 01:26:54

标签: ios database core-data model version

简短的问题:

我想在我的核心数据模型发生变化(新实体,新属性等)时在我的应用程序中运行某些代码。如何确定模型是否已更改?

只是一些伪代码:

    if (current_model_version != previous_model_version) {
    //do some code
    } else {
    // do some other code
    }

我猜我可能会使用versionHashes来执行此操作,或者isConfiguration:compatibleWithStoreMetadata:,但我不确定如何。

为了清晰起见,进行了一些编辑:“当前”和“上一次”中的“当前”一样,“上一次应用程序已启动”。

2 个答案:

答案 0 :(得分:9)

答案似乎是 isConfiguration:compatibleWithStoreMedia:

我在这里找到了一些有用的信息:

http://mipostel.com/index.php/home/70-core-data-migration-standard-migration-part-2

我这样设置:

- (BOOL)modelChanged
{
    NSError *error;
    NSURL * sourceURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"db.sqlite"];
    NSDictionary *sourceMetadata = [NSPersistentStoreCoordinator metadataForPersistentStoreOfType:NSSQLiteStoreType URL:sourceURL error:&error];
    BOOL isCompatible = [[self managedObjectModel] isConfiguration:nil compatibleWithStoreMetadata:sourceMetadata];

    return isCompatible;

}

'self'是我的共享数据存储,而不是必须去那里。

deanWombourne指出,这真正做的是确定数据是否可以自动迁移,因此它并不是我提出的问题的解决方案。在这种情况下,它确实满足了我的需求。

答案 1 :(得分:1)

如果您在XCode中设置新项目时勾选Core Data框,则会获得- (NSPersistentStoreCoordinator *)persistentStoreCoordinator的替换代码。

它尝试打开现有的sqlite文件(如果需要,使用轻量级迁移)。如果失败,则删除并重新创建商店。

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

    _persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];

    NSError *error = nil;

    NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
                            [NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
                            [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];

    if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:self.storeURL options:options error:&error])
    {
        NSLog(@"Couldn't open the store. error %@, %@", error, [error userInfo]);

        [self deleteSqliteFilesForStore:self.storeURL];

        if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:self.storeURL options:options error:&error])
        {
            NSLog(@"Unresolved error %@, %@", error, [error userInfo]);

            // or [NSException raise ...]
        }
        else
        {
            NSLog(@"Store deleted and recreated");

            // TEST DATA RE-INITIALIZATION CODE GOES HERE
        }
    }
    else
    {
        NSLog(@"Existing Store opened successfully");
    }

    return _persistentStoreCoordinator;
}

- (void)deleteSqliteFilesForStore:(NSURL *)storeURL
{
    NSURL *baseURL = [storeURL URLByDeletingPathExtension];

    // Delete the associated files as well as the sqlite file

    for (NSString *pathExtension in @[@"sqlite",@"sqlite-shm",@"sqlite-wal"])
    {
        NSURL *componentURL = [baseURL URLByAppendingPathExtension:pathExtension];

        BOOL fileExists = [[NSFileManager defaultManager] fileExistsAtPath:[componentURL path]];
        if(fileExists)
        {
            [[NSFileManager defaultManager] removeItemAtPath:[componentURL path] error:nil];
        }
    }
}