2012-11-21 62 views
0

我遵循this指南在我的非基于文档的应用程序中实现核心数据迁移和版本控制。我做了报道驾驶,但是当我开始应用程序告诉我,我打开的模型不受支持。我怎样才能解决这个问题?核心数据迁移和版本控制

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

    NSManagedObjectModel *mom = [self managedObjectModel]; 
    if (!mom) { 
     NSLog(@"%@:%@ No model to generate a store from", [self class], NSStringFromSelector(_cmd)); 
     return nil; 
    } 

    NSFileManager *fileManager = [NSFileManager defaultManager]; 

    NSURL *applicationFilesDirectory = [self applicationFilesDirectory]; 
    NSURL *storeURL = [[self applicationFilesDirectory] URLByAppendingPathComponent:@"Preventivi.storedata"]; 

    NSError *error = nil; 
    //Turn on automatic store migration 
    NSMutableDictionary *optionsDictionary = [NSMutableDictionary dictionary]; 
    [optionsDictionary setObject:[NSNumber numberWithBool:YES] forKey:NSMigratePersistentStoresAutomaticallyOption]; 
    NSDictionary *properties = [applicationFilesDirectory resourceValuesForKeys:@[NSURLIsDirectoryKey] error:&error]; 

    if (!properties) { 
     BOOL ok = NO; 
     if ([error code] == NSFileReadNoSuchFileError) { 
      ok = [fileManager createDirectoryAtPath:[applicationFilesDirectory path] withIntermediateDirectories:YES attributes:nil error:&error]; 
      NSURL *defaultStoreURL = [[NSBundle mainBundle] URLForResource:@"Preventivi" withExtension:@"storedata"]; 
      if (defaultStoreURL) { 
       [fileManager copyItemAtURL:defaultStoreURL toURL:storeURL error:NULL]; 
      } 
     } 
     if (!ok) { 
      [[NSApplication sharedApplication] presentError:error]; 
      return nil; 
     } 
    } else { 
     if (![properties[NSURLIsDirectoryKey] boolValue]) { 
      // Customize and localize this error. 
      NSString *failureDescription = [NSString stringWithFormat:@"Expected a folder to store application data, found a file (%@).", [applicationFilesDirectory path]]; 

      NSMutableDictionary *dict = [NSMutableDictionary dictionary]; 
      [dict setValue:failureDescription forKey:NSLocalizedDescriptionKey]; 
      error = [NSError errorWithDomain:@"YOUR_ERROR_DOMAIN" code:101 userInfo:dict]; 

      [[NSApplication sharedApplication] presentError:error]; 
      return nil; 
     } 
    } 

    NSURL *url = [applicationFilesDirectory URLByAppendingPathComponent:@"Preventivi.storedata"]; 
    NSPersistentStoreCoordinator *coordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:mom]; 
    if (![coordinator addPersistentStoreWithType:NSXMLStoreType configuration:nil URL:url options:nil error:&error]) { 
     [[NSApplication sharedApplication] presentError:error]; 
     return nil; 
    } 
    _persistentStoreCoordinator = coordinator; 

    return _persistentStoreCoordinator; 
} 

回答

0

看来你已经配置你的核心数据堆栈使用自动迁移。并继续更改模型而不使用版本控制。

你必须使用版本模型。如果您在修改模型之前未创建模型版本,则自动迁移将不起作用。为了在每次修改之前使自动迁移工作,您应该创建一个新的模型版本并修改该新版本。

例如,你想添加几个属性的实体,并添加另一个实体,您:

  1. 创建新模型版本(选择模型文件,编辑 - >添加模式 版本...);
  2. 选择新版本并添加属性和实体。

而且,如果您使用配置或不使用配置,只要自动迁移在配置方面存在问题。

0

你可以告诉应用程序抛出错误的位置吗?如果它在最后一行中,则可以尝试将storeType NSXMLStoreType更改为NSSQLiteStoreType。

if (![coordinator addPersistentStoreWithType:NSXMLStoreType configuration:nil URL:url options:nil error:&error]) 

if (![coordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:url options:options error:&error]) 

对于这一点,你必须也更改后缀为 “源码”。

NSURL *url = [NSURL fileURLWithPath: [applicationFilesDirectory stringByAppendingPathComponent: @"Preventivi.sqlite"]] 

NSURL *defaultStoreURL = [[NSBundle mainBundle] URLForResource:@"Preventivi" withExtension:@"sqlite"]; 

或者,如果你已经有了一个解决方案,你可以分享这个:) 但是我的代码相比,有没有真正的差异(只有一个选项的详细

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

并且您在添加持久存储时不使用该选项^^ )

我希望这有助于:)