macos - 没有 "document changed"警告的手动核心数据架构迁移?

标签 macos core-data migration mapping-model datamodel

我的基于 Core Data 文档的应用程序(仅限 10.5)的数据模型位于
框架,因此使用核心数据映射自动升级架构
模型似乎不起作用。看来 Core Data 机器
当他们找不到合适的数据模型或映射模型时
不在应用程序的主包中。所以,而不是使用自动
迁移,我正在手动运行迁移configurePersistentStoreCoordinatorForURL:ofType:...在我的NSPersistenDocument子类(下面的代码)。我迁移持久的
存储到一个临时文件,然后覆盖现有文件,如果
迁移成功。该文档然后显示一个错误
消息“此文档的文件已被另一个应用程序更改
因为你打开或保存了它。”当我尝试保存时。就像其他人一样
列表已经指出,这是由于我修改了
文档的文件“在其背后”。我尝试更新文档的
文件修改日期,如下所示,但随后出现错误对话框
带有消息“文档“test.ovproj”的位置不能
确定。”当我尝试保存时。我不太确定这是什么原因
错误,但用一个不必要的消息(在这种情况下)换另一个
不是我想要的。

任何人都可以提供一些指导吗?有没有办法手动升级
不触发其中之一的文档持久存储的架构
这些(在这种情况下是不必要的)警告?

用于升级我的子类中的数据存储的代码-configurePersistentStoreCoordinatorForURL:ofType:... :

if(upgradeNeeded) {
           NSManagedObjectModel *sourceModel = [NSManagedObjectModel mergedModelFromBundles:VUIModelBundles() orStoreMetadata:meta];

           if(sourceModel == nil) {
               *error = [NSError errorWithDomain:VUIErrorDomainn ode:VUICoreDataErrorCode localizedReason:BWLocalizedString(@"Unable to find original data model for project.")];
               return NO;
           }

           NSManagedObjectModel *destinationModel = [self managedObjectModel];

           NSMigrationManager *migrationManager = [[NSMigrationManager alloc] initWithSourceModel:sourceModel destinationModel:destinationModel];
           NSMappingModel *mappingModel = [NSMappingModel mappingModelFromBundles:VUIModelBundles() forSourceModel:sourceModel destinationModel:destinationModel];
           if(mappingModel == nil) {
               *error = [NSError errorWithDomain:VUIErrorDomain code:VUICoreDataErrorCode localizedReason:BWLocalizedString(@"Unable to find mapping model to convert project to most recent project format.")];
               return NO;
           }

           @try {
               //move file to backup
               NSAssert([url isFileURL], @"store url is not a file URL");

               NSString *tmpPath = [NSString tempFilePath];
               id storeType = [meta objectForKey:NSStoreTypeKey];
               if(![migrationManager migrateStoreFromURL:url
                                                    type:storeType
                                                 options:storeOptions
                                        withMappingModel:mappingModel
                                       toDestinationURL:[NSURLfileURLWithPath:tmpPath]
                                         destinationType:storeType
                                      destinationOptions:storeOptions
                                                   error:error]) {

                   return NO;
               } else {
                   //replace old with new
                   if(![[NSFileManager defaultManager] removeItemAtPath:[url path] error:error] ||
                      ![[NSFileManager defaultManager] moveItemAtPath:tmpPath toPath:[url path] error:error]) {
                       return NO;
                   }

                   // update document file modification date to prevent warning (#292)
                   NSDate *newModificationDate = [[[NSFileManager defaultManager] fileAttributesAtPath:[url path] traverseLink:NO] bjectForKey:NSFileModificationDate];
                   [self setFileModificationDate:newModificationDate];
               }
           }
           @finally {
               [migrationManager release];
           }
       }
   }

   return [super configurePersistentStoreCoordinatorForURL:url ofType:fileType modelConfiguration:configuration storeOptions:storeOptions error:error];

最佳答案

我没有遇到过这种特殊情况,但我有一些猜测。首先,当你想切换文件时,不要使用 -removeItemAtPath: 和 -moveItemAtPath: ,而是使用 FSExchangeObjects() 函数。 NSDocument 使用 FSRefs 来跟踪文件,除非您使用 FSExchangeObjects(),否则它会意识到它正在查看一个完全不同的文件。

其次,您可以通过覆盖 -managedObjectModel 手动设置文档的托管对象模型,特别是使用 +mergedModelFromBundles: 方法从您的框架加载模型。根据文档,默认情况下它应该合并主包和所有链接框架中的任何模型,所以这应该只对动态加载的包是必要的。不知道为什么这对您不起作用,但我还没有尝试过。要找出要搜索的包,NSBundle 的 +bundleForClass: 方法是您的 friend 。

关于macos - 没有 "document changed"警告的手动核心数据架构迁移?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/380076/

相关文章:

objective-c - 在 10.9 上以编程方式启用对辅助设备的访问

ios - 如何将 SQLite 表导入 Core Data(SQLite 也是如此)

linux - os x 的替代 iproute2 是什么

swift - Xcode 没有这样的模块 : 'PackageDescription'

ios - 使用 NSPredicate 时如何指定 Int 类型的范围

swift - 从 CSV 在 Core Data 中创建 2000 万条记录 - macOS

android - ActiveAndroid迁移不报错(代码0),语法错误

android - 如何在一个应用程序中处理 SQLiteOpenHelper 和 RoomDatabase?

node.js - Knex 迁移不创建表

objective-c - 如何动态更改nstableview中显示的行数