手动核心数据版本控制

发布于 2024-11-16 10:16:43 字数 637 浏览 0 评论 0原文

我开发了一个应用程序,iCollege,现在我想做该应用程序好多了。
在测试时我想从备份中恢复数据。在启动 iCollege 时,应用程序崩溃,因为它无法由 Core Data 进行版本控制。我现在的问题是是否可以手动对核心数据文件进行版本控制,即遍历现有文件的每个托管对象并将对象适合活动模型版本。

这样的事情可能吗?

编辑:非常感谢您的快速而详细的答复。我认为我对我的问题的解释不太好。这是我的问题的另一个描述。
我有一个使用 Core Data 创建的文件,其中包含实体 CourseTeacher 的一些对象。我用这个文件替换我的应用程序的核心数据文件。当应用程序下次启动时,我想调用一个方法,该方法读取带有 CourseTeacher 对象的文件的托管对象,并将其转换为实体,例如主题教授。属性也可能会改变。我的问题是我是否可以做到这一点,即我可以自己版本化核心数据文件吗?
我希望我的问题现在可以检查。 :-)

I developed an app, iCollege, and now I want to make the app much better.
While the testing I wanted to restore the data from a backup. At launching iCollege the app crashes because it could not be versioned by Core Data. My question now is if it is possible to version a Core Data file manually, i.e. going through every Managed Object of the existing file and fit the objects to the active Model Version.

Is something like that possible?

EDIT: Thank you very much for your fast and detailed answer. I think that I explained my question not very good. Here is another description of my problem.
I have a file created with Core Data with a few Objects of the entities Course and Teacher. I replace the Core Data file of my app with this file. When the app launches the next time I want to call a method which reads the Managed Objects of the file with the objects of Course and Teacher and convert it into the Entities, e.g. Subject and Professor. The attributes may be changed, too. My question is if I can do this, i.e. can I version the Core Data file on my own?
I hope my question is now checkable. :-)

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

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

发布评论

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

评论(2

可是我不能没有你 2024-11-23 10:16:43

虽然从理论上讲,您可以手动迁移数据,但这可能不值得。您想要使用自动轻量级迁移

要执行自动轻量级迁移,您需要设置两个数据模型,然后在代码中告诉Core Data执行迁移。这意味着您在阅读完本文之前不应修改数据模型。如果有,(自动或手动)恢复旧模型。您将需要它来进行迁移。自动轻量级迁移的工作原理如下:

首先,您需要将模型版本添加到数据模型中。选择现有模型,然后从 Editor 菜单添加版本:

Select the model

添加模型版本

系统将提示您命名数据模型并选择其所基于的现有模型。

在此处输入图像描述

现在,继续对新模型进行更改。当您完成后,您需要告诉 Core Data 使用这个新模型作为当前版本。我们还没有掌握代码,所以这部分很简单。 (代码也很简单。)在右侧面板上,选择活动模型,如下所示:

在此处输入图像描述

确保在左侧导航器中选择您的型号,否则您可能看不到右侧的选项。你最终应该得到这样的结果:

在此处输入图像描述

(我实际上在这里使用版本 2 而不是版本 3 ,但想法是相同的。)

现在,您需要快速更改代码,以便 Core Data 知道为您进行迁移。

在应用程序委托中的 persistentStoreCoordinator 方法内部,将此行:更改

if (![__persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:options error:&error]){

为以下内容(在 if 语句之前添加行):

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


if (![__persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:options error:&error]){

您实际上已经将 Core Data 传递给了选项字典告诉它为您迁移数据存储。 (仔细看看前面的代码,读几遍后就会明白了。)

编辑:您可能可以做您想做的事。如果我理解正确的话,您应该创建一个新的模型版本,执行轻量级迁移,然后他们手动进行您想要的更改。我上面的答案仍然有效,只是您之后需要进行一些手动更改。

While theoretically, you can migrate your data manually, it's probably not worth the effort. You want to use automatic lightweight migration.

To perform automatic lightweight migration, you need to have two data models set up, then in code, you tell Core Data to perform the migration. This means that you should not modify your data model until you finish reading this. If you have, (automatically or manually) restore your old model. You'll need it to do the migration. Here's how automatic lightweight migration works:

First, you need to add a model version to your data model. Select the existing model and then add a version from the Editor menu:

Select the model

Add a Model Version

You will be prompted to name your data model and choose which existing model to base it on.

enter image description here

Now, go ahead and make your changes to the new model. When you are done, you need to tell Core Data to use this new model as the current version. We're not up to the code yet, so this part is easy. (The code is easy too.) On the right hand side panel, choose the active model, as shown here:

enter image description here

Make sure that your model is selected in the left hand navigator, or else you might not see the options on the right. You should end up with something like this:

enter image description here

(I'm actually using version 2 here instead of version 3, but the idea is the same.)

Now, you need to make a quick change to your code so that Core Data knows to do the migration for you.

Inside of your persistentStoreCoordinator method in your app delegate, change this line:

if (![__persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:options error:&error]){

to the following (adding in the line preceding the if statement):

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


if (![__persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:options error:&error]){

You've essentially passed Core Data a dictionary of options which tells it to migrate the data store for you. (Take a close look at the preceding code, it will make sense after a couple of read throughs.)

Edit: You probably can do what you want. If I understand you correctly, you should create a new model version, perform lightweight migration, and them manually make the changes that you want. My above answer still stands, except that you will want to make some manual changes afterward.

孤蝉 2024-11-23 10:16:43

您可以按如下方式执行此操作。核心数据允许您将多个持久存储添加到 NSPersistentStoreCoordinator,因此您需要与协调器关联的两个存储。请注意,不可能使用两种不同的托管对象模型 (MOM),您的所有商店只能使用一个 MOM。

虽然这看起来相当困难,但考虑到 Core Data 也允许使用配置,它却足够简单。配置具有名称和关联的实体集。这些集合可能会重叠,也就是说,给定的实体可能会以多种配置出现。请参阅相关的 文档

现在,您可以通过在不同的商店中拥有不同的实体来轻松处理您的问题,
创建一个模型,该模型将是您要使用的所有实体的超集
处理(或至少是联合)并将您需要的子集定义为配置。然后,对于每个单独的商店,您指定关联的配置。

像这样的东西(只是一个示例片段):

NSPersistentStoreCoordinator *coordinator = [[NSPersistentStoreCoordinator alloc] init];
[coordinator addPersistentStoreWithType:type configuration:@"CourseAndTeacher" URL:aURL options:nil error:NULL];
[coordinator addPersistentStoreWithType:type configuration:@"SubjectAndProfessor" URL:anotherURL options:nil error:NULL];

NSManagedObjectContext *context = [[NSManageObjectContext alloc] init];
[context setPersistentStoreCoordinator:coordinator];

You can do this as follows. Core data allows you adding multiple persistent stores to a NSPersistentStoreCoordinator, so you need two stores associated to your coordinator. Note that it is not possible to use two different Managed Object Models (MOMs), you can only have one MOM for all of your stores.

While this may appear to be rather difficult, it is instead simple enough, given that Core Data also allows using configurations. A configuration has a name and an associated set of entities. The sets may overlap—that is, a given entity may appear in more than one configuration. See the associated documentation

You can now easily deal with your problem by having different entities in different stores,
creating a model which will be a superset of all the entities you're going
to deal with (or at least the union) and that defines the subsets you need as configurations. Then, for each individual store, you specify the associated configuration.

Something like (just an example snippet):

NSPersistentStoreCoordinator *coordinator = [[NSPersistentStoreCoordinator alloc] init];
[coordinator addPersistentStoreWithType:type configuration:@"CourseAndTeacher" URL:aURL options:nil error:NULL];
[coordinator addPersistentStoreWithType:type configuration:@"SubjectAndProfessor" URL:anotherURL options:nil error:NULL];

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