Manually transferring a data entry scheme without a “document change” warning?

The data model for my application based on the main document (only for 10.5) is in, so the automatic updating of the scheme using the master data mapping model does not work. It seems that the Core Data equipment does not find suitable data models or matching models when they are not included in the main application package. Thus, instead of using automatic migration, I perform manual migration configurePersistentStoreCoordinatorForURL:ofType:... in my Subclass NSPersistenDocument (code below). I am moving the persistent save to a temporary file and then overwrite the existing file if the migration is successful. Then, an error occurs in the document with the message "This document file has been modified by another application since you opened or saved it." When I try to save. the list indicated, this is due to my modification of the document file "behind him." I tried updating the document file modification date, as shown below, but then I get an error dialog box with the message "Document location" test.ovproj "cannot be determined." When I try to save, I'm less sure about the reason for this error, but trading one unnecessary message (in this case) for another is not quite what I was going to.

Can anyone offer some kind of guidance? Is there a way to manually update the schema for a persistent document store without running one of these (in this case, unnecessary) warnings?

The code for updating the data warehouse in my subclasses is -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]; 
+4
source share
3 answers

I have not come across this particular situation, but I have a few guesses. First, instead of using -removeItemAtPath: and -moveItemAtPath: if you want to switch files, use the FSExchangeObjects () function instead. NSDocument uses FSRefs to track the file, and if you do not use FSExchangeObjects (), it will understand that it is looking at a completely different file.

Secondly, you can manually configure the model of the object with a managed document by overriding -managedObjectModel, in particular, using the + mergedModelFromBundles: method to load models from your structure. According to the docs, it should by default integrate any models in the main package and in all related frames, so this is only necessary for dynamically loaded packages. I don’t know why this does not work for you, but I have not tried it. To find out which packages to look for, the NSBundle + bundleForClass: method is your friend.

+1
source

Beware of FSExchangeObjects ()! It does not support all types of volumes, see BSupportsFSExchangeObjects. I'm looking for a replacement. The option looks like MoreFilesX FSExchangeObjectsCompat or 10.5 FSReplaceObjects ().

+1
source

10 years later ... I encountered the same problem, and with the new API for NSDocument you can update the documentModificationDate file with the new date of the updated file after the migration

 migrate() if let newModificationDate = try? NSFileManager.defaultManager().attributesOfItemAtPath(url.path!)[NSFileModificationDate] as? NSDate { self.fileModificationDate = newModificationDate } 

after that you can call super.configurePersistentStoreCoordinatorForURL...

This is because NSDocument sets the file modification date even before calling readFromURL:ofType . See Document Initialization Message Flow

0
source

All Articles