【问题标题】:How to update Core Data and maintain user-saved data?如何更新 Core Data 并维护用户保存的数据?
【发布时间】:2014-11-15 09:57:59
【问题描述】:

我在 App Store 上有一个使用 Core Data 的应用,我想进行更新。我使用预加载的 sqlite 文件来创建persistentStore。模型中有两个实体,其中一个包含用户保存的数据。

我的问题:我想用新的预加载 sqlite 更新现有的核心数据,但保留用户保存的数据。有没有办法将预加载文件的新数据与用户保存的数据合并?

模型保持不变;我没有添加任何新实体或属性,所以我认为迁移不合适(我可能错了)。

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

   NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"CreatureData.sqlite"];

   if (![[NSFileManager defaultManager] fileExistsAtPath:[storeURL path]]) {
      NSURL *preloadURL = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"CreatureData" ofType:@"sqlite"]];
      NSLog(@"JUST LOADED COREDATA SQLITE");
      NSError* err = nil;

      if (![[NSFileManager defaultManager] copyItemAtURL:preloadURL toURL:storeURL error:&err]) {
         NSLog(@"Oops, couldn't copy preloaded data");
      }
   } else {
      NSLog(@"Core Data SQLITE already exists");
   }


   NSError *error = nil;
   _persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
   if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]) {

       NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
       //abort();
   }

return _persistentStoreCoordinator;
}

编辑:

NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"CreatureData.sqlite"];
NSURL *secondStoreURL = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"CreatureData" ofType:@"sqlite"]];

if (![[NSFileManager defaultManager] fileExistsAtPath:[storeURL path]]) {
      NSURL *preloadURL = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"CreatureData" ofType:@"sqlite"]];
      NSLog(@"JUST LOADED COREDATA SQLITE");
      NSError* err = nil;

      if (![[NSFileManager defaultManager] copyItemAtURL:preloadURL toURL:storeURL error:&err]) {
         NSLog(@"Oops, couldn't copy preloaded data");
      }
   }

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

   NSDictionary *options = @{NSMigratePersistentStoresAutomaticallyOption : @YES,
                             NSInferMappingModelAutomaticallyOption : @YES };

   if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:@"UserSavedData" URL:storeURL options:options error:&error]) {
       NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
   }
   if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:@"StaticTableData" URL:secondStoreURL options:options error:&error]) {
       NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
   }

【问题讨论】:

    标签: sqlite core-data user-input updates


    【解决方案1】:

    Apple 建议您将静态数据和用户数据分开,在这种情况下分为 2 个持久存储。您可以执行以下操作之一:

    第一个也是更可取的选项,您为用户数据使用单独的存储。您需要更新数据模型以适应两个存储,因此这将是一个轻量级迁移。

    然后,您将在第一次启动时从现有的 sqlite 存储中提取用户数据,并将它们存储到新的动态存储中。然后,您可以删除旧的 sqlite 存储。

    第二个选项是保留当前设置。首次运行时,使用不同的名称复制您的新文件,然后从旧存储中提取用户数据并将其复制到新存储中。然后删除旧商店。

    【讨论】:

    • 针对第一个选项,您说“更新数据模型以容纳两个商店”。这是否意味着我应该将现有模型拆分为两个新模型(一个用于用户数据,一个用于静态数据)?如果是这样,您是否可以在新模型移除实体的情况下执行轻量级迁移?
    • 差不多。是的,轻量级迁移应该是可能的。诀窍是使用“配置”来处理这两个商店,但它们在同一个模型中被引用。请参阅核心数据编程指南中的Using Persistent Stores。
    • 我一直在查看 Persistent Stores 和 Managed Object Model Configurations 的文档,但我仍然感到困惑。您是说我应该通过添加两个配置(每个实体一个)来更新模型,然后将每个配置加载到他们自己的商店中吗?您能否澄清在同一模型中引用两家商店的问题?
    • 也许您应该再次阅读文档。一种模型 - 两种配置,每个存储一个 - 一个只读存储和一个读写存储。
    • 我在查看文档后进行了一些试验和错误,但我在配置方面遇到了问题。我为每个实体创建了一个带有配置的新模型。当我将持久存储添加到协调器时,我收到一个错误:“不能将同一个存储添加两次。”我将在编辑中发布上面的代码。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-12-14
    • 1970-01-01
    • 2011-05-13
    • 2014-11-03
    • 2020-04-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多