“自动轻量级迁移”的实现适用于核心数据 (iPhone)

发布于 2024-08-22 06:06:52 字数 1795 浏览 0 评论 0原文

我想让我的应用程序能够在添加时进行自动轻量级迁移 我的核心数据模型的新属性。

在苹果的指南中,这是我能找到的关于该主题的唯一信息:

自动轻量级迁移

请求自动轻量化 迁移,您设置适当的标志 在您传入的选项字典中 addPersistentStoreWithType:配置:URL:选项:错误:。 需要设置对应的值 到两个 NSMigratePersistentStoresAutomatically选项 和 NSInferMappingModelAutomatically选项 是的关键:

NSError *error;
NSURL *storeURL = <#The URL of a persistent store#>;
NSPersistentStoreCoordinator *psc = <#The coordinator#>;
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
    [NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
    [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];
 
if (![psc addPersistentStoreWithType:<#Store type#>
    configuration:<#Configuration or nil#> URL:storeURL
    options:options error:&error]) {
    // Handle the error.
}

我的 NSPersistentStoreCoordinator 是以这种方式初始化的:

- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {
    
    if (persistentStoreCoordinator != nil) {
        return persistentStoreCoordinator;
    }
    
    NSURL *storeUrl = [NSURL fileURLWithPath: [[self applicationDocumentsDirectory] stringByAppendingPathComponent: @"FC.sqlite"]];
    
    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;
}

我无法确定应在何处以及如何添加 Apple 代码以使自动轻量级迁移正常工作?

I would like to make my app able to do an automatic lightweight migration when I add
new attributes to my core data model.

In the guide from Apple this is the only info on the subject I could find:

Automatic Lightweight Migration

To request automatic lightweight
migration, you set appropriate flags
in the options dictionary you pass in
addPersistentStoreWithType:configuration:URL:options:error:.
You need to set values corresponding
to both the
NSMigratePersistentStoresAutomaticallyOption
and the
NSInferMappingModelAutomaticallyOption
keys to YES:

NSError *error;
NSURL *storeURL = <#The URL of a persistent store#>;
NSPersistentStoreCoordinator *psc = <#The coordinator#>;
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
    [NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
    [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];
 
if (![psc addPersistentStoreWithType:<#Store type#>
    configuration:<#Configuration or nil#> URL:storeURL
    options:options error:&error]) {
    // Handle the error.
}

My NSPersistentStoreCoordinator is initialized in this way:

- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {
    
    if (persistentStoreCoordinator != nil) {
        return persistentStoreCoordinator;
    }
    
    NSURL *storeUrl = [NSURL fileURLWithPath: [[self applicationDocumentsDirectory] stringByAppendingPathComponent: @"FC.sqlite"]];
    
    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;
}

I am having trouble seeing where and how I should add the Apple code to get the Automatic Lightweight Migration working?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

万劫不复 2024-08-29 06:06:54

这就是我所做的自动轻量级迁移(来源:http://brainwashinc.wordpress.com/2010/01/18/iphone-coredata-automatic-light-migration/)

1. 在应用程序委托中设置自动迁移的持久存储选项。

将您的 persistenceStoreCoordinator 创建更改为此(替换 YOURDB):

- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {

  if (persistentStoreCoordinator != nil) {
    return persistentStoreCoordinator;
  }

  NSURL *storeUrl = [NSURL fileURLWithPath: [[self applicationDocumentsDirectory] stringByAppendingPathComponent: @"YOURDB.sqlite"]];

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

  NSError *error = nil;
  persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel: [self managedObjectModel]];
  if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrl options:options error:&error]) {
    // Handle error
  }

  return persistentStoreCoordinator;
}

2. 版本化您的数据模型并编辑新文件。

选择您的 xcdatamodel 文件
设计->数据模型->添加模型版本(展开您的 xcdatamodeld 项目)
选择“2”(或更高版本)文件,设计->数据模型->设置当前版本(编辑此版本)

3. 在应用程序委托中指定 momd 资源。

将你的 ManagedObjectModel 实现更改为此(替换 YOURDB)

- (NSManagedObjectModel *)managedObjectModel {

  if (managedObjectModel != nil) {
    return managedObjectModel;
  }

  NSString *path = [[NSBundle mainBundle] pathForResource:@"YOURDB" ofType:@"momd"];
  NSURL *momURL = [NSURL fileURLWithPath:path];
  managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:momURL];

  return managedObjectModel;
}

This is what I did to make Automatic Lightweight Migration (Source: http://brainwashinc.wordpress.com/2010/01/18/iphone-coredata-automatic-light-migration/)

1. Set the Persistent Store options for automatic migration in the app delegate.

Change your persistentStoreCoordinator creation to this (replace YOURDB):

- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {

  if (persistentStoreCoordinator != nil) {
    return persistentStoreCoordinator;
  }

  NSURL *storeUrl = [NSURL fileURLWithPath: [[self applicationDocumentsDirectory] stringByAppendingPathComponent: @"YOURDB.sqlite"]];

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

  NSError *error = nil;
  persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel: [self managedObjectModel]];
  if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrl options:options error:&error]) {
    // Handle error
  }

  return persistentStoreCoordinator;
}

2. Version your Data Model and Edit the new file.

Select your xcdatamodel file
Design -> Data Model -> Add Model Version (expand your xcdatamodeld item)
Select the “2″ (or later) file, Design -> Data Model -> Set Current Version (edit this version)

3. Specify the momd resource in app delegate.

Change your managedObjectModel implementation to this (replace YOURDB)

- (NSManagedObjectModel *)managedObjectModel {

  if (managedObjectModel != nil) {
    return managedObjectModel;
  }

  NSString *path = [[NSBundle mainBundle] pathForResource:@"YOURDB" ofType:@"momd"];
  NSURL *momURL = [NSURL fileURLWithPath:path];
  managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:momURL];

  return managedObjectModel;
}
洒一地阳光 2024-08-29 06:06:54

起初,上述解决方案对我不起作用。返回的 ManagedObjectModel 为 0x0。
我认为这是因为我重命名了不同模型文件的文件名。
如果您严格按照上面的说明进行操作,那么一切都会正常。

但是,如果您确实更改模型文件名,则可以手动选择“当前”模型文件:
假设您的原始模型文件是 MYMODEL.xcdatamodel
执行上面的添加模型步骤后,这将变成目录 MY.xcdatamodeld
在它下面有 MYMODEL.xcdatamodel 和 MYMODEL 2.xcdatamodel
将新模型文件重命名为您想要的任何名称,例如,假设您删除了 MYMODEL2.xcdatamodel 的空间并编辑其内容。
现在在上面的代码中做

NSString *path = [mainBundle pathForResource:@"MYMODEL2" ofType:@"mom" inDirectory:@"MYMODEL.momd"];

At first, the above solution didn't work for me. The returned managedObjectModel was 0x0.
I think this is because I renamed the file names of the different model files.
If you follow the instructions above to the letter then it all works.

However if you do change model file names then you can select the "current" model file manually:
Lets say your original model file was MYMODEL.xcdatamodel
after doing the add model step above this turns into a directory MY.xcdatamodeld
and below it you have MYMODEL.xcdatamodel and MYMODEL 2.xcdatamodel
rename the new model file to whatever you want, for example lets say you removed the space to MYMODEL2.xcdatamodel and edit its content.
Now in the above code do

NSString *path = [mainBundle pathForResource:@"MYMODEL2" ofType:@"mom" inDirectory:@"MYMODEL.momd"];
陌路黄昏 2024-08-29 06:06:54

我认为这补充了最后一个答案。

我发现捆绑资源和 .sqlite 名称的用法一开始确实令人困惑。 Bundle资源名称是否会随着版本的变化而变化? .sqlite 名称是否更改?我现在已经开始迁移,并且了解到捆绑包模型名称是指 XCode 中包含所有模型的目录/文件夹的名称,而不是该目录中模型版本的名称。

当您将 modelResource 名称指定为:

NSURL *modelURL = [[NSBundle mainBundle] URLForResource:modelResource withExtension:@"momd"];
NSManagedObjectModel *theManagedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];

该 modelResource 名称是 Xcode 中模型的目录/文件夹。

当您这样做时:

    NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:storeFileName];
    NSError *error = nil;

    if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:options error:&error]) {
        // handle error
    }

storeFileName 是 Documents 文件夹/目录中的 .sqlite 文件的名称(这不在捆绑包中)。

此外,当您从一个模型版本迁移到另一模型版本时,默认情况下,.sqlite 文件名保持不变。

I think this adds onto the last answer.

I found the usage of the bundle resource and .sqlite names really confusing at first. Does the bundle resource name change with the version change? Does the .sqlite name change? I've now got my migration working, and learned that the bundle model name refers to the name of the directory/folder in XCode containing all the models, not the name of the model versions within that directory.

When you give a modelResource name to:

NSURL *modelURL = [[NSBundle mainBundle] URLForResource:modelResource withExtension:@"momd"];
NSManagedObjectModel *theManagedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];

That modelResource name is the directory/folder for the models in Xcode.

When you do:

    NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:storeFileName];
    NSError *error = nil;

    if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:options error:&error]) {
        // handle error
    }

The storeFileName is the name of your .sqlite file in the Documents folder/directory (this is not in the bundle).

Also, when you migrate from one model version to another model version, by default, the .sqlite file name remains the same.

鼻尖触碰 2024-08-29 06:06:54

奥斯卡,针对你的问题,我最初发现了同样的事情。我建议删除新的 .xcdatamodeld 文件并将其重新添加到您的项目中,然后重建。希望有帮助!

Oscar, in response to your issue, I found the same thing initially. I would suggest deleting and re-adding the new .xcdatamodeld file to your project, and then rebuilding. Hope that helps!

站稳脚跟 2024-08-29 06:06:54

Swift 3 解决方案

1.在应用程序委托中设置用于自动迁移的持久存储选项。

将 persistenceStoreCoordinator 创建更改为此(替换 SingleViewCoreData.sqlite):

lazy var persistentStoreCoordinator: NSPersistentStoreCoordinator = {


let coordinator: NSPersistentStoreCoordinator = NSPersistentStoreCoordinator(managedObjectModel: self.managedObjectModel)
let url = self.applicationDocumentsDirectory.appendingPathComponent("SingleViewCoreData.sqlite")

let options = [
  NSMigratePersistentStoresAutomaticallyOption : Int(true),
  NSInferMappingModelAutomaticallyOption : Int(true)
]

do {

  try coordinator.addPersistentStore(ofType: NSSQLiteStoreType, configurationName: nil, at: url, options: options)

} catch {

  print(error)
}

return coordinator

}()

2.对您的数据模型进行版本控制并编辑新文件。

选择您的 xcdatamodel 文件编辑器 > 添加模型版本 - 为您的新模型添加名称

Swift 3 Solution

1. Set the Persistent Store options for automatic migration in the app delegate.

Change your persistentStoreCoordinator creation to this (replace SingleViewCoreData.sqlite):

lazy var persistentStoreCoordinator: NSPersistentStoreCoordinator = {


let coordinator: NSPersistentStoreCoordinator = NSPersistentStoreCoordinator(managedObjectModel: self.managedObjectModel)
let url = self.applicationDocumentsDirectory.appendingPathComponent("SingleViewCoreData.sqlite")

let options = [
  NSMigratePersistentStoresAutomaticallyOption : Int(true),
  NSInferMappingModelAutomaticallyOption : Int(true)
]

do {

  try coordinator.addPersistentStore(ofType: NSSQLiteStoreType, configurationName: nil, at: url, options: options)

} catch {

  print(error)
}

return coordinator

}()

2. Version your Data Model and Edit the new file.

Select your xcdatamodel file Editor>Add Model Version - add a name for your new model

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文