Easy migration of NSPsistentDocument

I am trying to make an easy migration of SQLite storage to Core Data. Work on Lion 10.7.3 with Xcode 4.3.1.

In my subclass of NSPersistentDocument (AccountDocument), I overridden the method used to configure the persistent storage coordinator to get the correct options for migration:

- (BOOL)configurePersistentStoreCoordinatorForURL:(NSURL *)url ofType:(NSString *)fileType modelConfiguration:(NSString *)configuration storeOptions:(NSDictionary *)storeOptions error:(NSError **)error { NSMutableDictionary *newStoreOptions; if (storeOptions == nil) { newStoreOptions = [NSMutableDictionary dictionary]; } else { newStoreOptions = [storeOptions mutableCopy]; } [newStoreOptions setObject:[NSNumber numberWithBool:YES] forKey:NSMigratePersistentStoresAutomaticallyOption]; [newStoreOptions setObject:[NSNumber numberWithBool:YES] forKey:NSInferMappingModelAutomaticallyOption]; BOOL result = [super configurePersistentStoreCoordinatorForURL:url ofType:fileType modelConfiguration:configuration storeOptions:newStoreOptions error:error]; return result; } 

(Thanks to Malcolm Crawford for this tip: http://homepage.mac.com/mmalc/CocoaExamples/controllers.html )

When I run the application, it does not work in the implementation of NSPersistentDocument -managedObjectModel :

 * thread #1: tid = 0x2703, 0x00007fff931d9350 libobjc.A.dylib`objc_msgSend_vtable13 + 16, stop reason = EXC_BAD_ACCESS (code=13, address=0x0) frame #0: 0x00007fff931d9350 libobjc.A.dylib`objc_msgSend_vtable13 + 16 frame #1: 0x00007fff8935e975 CoreData`-[NSKnownKeysDictionary1 _setValues:retain:] + 197 frame #2: 0x00007fff8935f288 CoreData`_newReadModelFromBytes + 648 frame #3: 0x00007fff8935b93e CoreData`+[NSManagedObjectModel(_NSManagedObjectModelPrivateMethods) _newModelFromOptimizedEncoding:error:] + 9310 frame #4: 0x00007fff89359451 CoreData`-[NSManagedObjectModel(_NSManagedObjectModelPrivateMethods) initWithContentsOfOptimizedURL:] + 305 frame #5: 0x00007fff89358d7b CoreData`-[NSManagedObjectModel initWithContentsOfURL:] + 443 frame #6: 0x00007fff893e9519 CoreData`+[NSManagedObjectModel mergedModelFromBundles:] + 377 frame #7: 0x00007fff8ded7037 AppKit`-[NSPersistentDocument managedObjectModel] + 301 frame #8: 0x00007fff8ded70b3 AppKit`-[NSPersistentDocument managedObjectContext] + 75 frame #9: 0x00007fff8ded6e3f AppKit`-[NSPersistentDocument _persistentStoreCoordinator] + 18 frame #10: 0x00007fff8ded6b5d AppKit`-[NSPersistentDocument configurePersistentStoreCoordinatorForURL:ofType:modelConfiguration:storeOptions:error:] + 51 frame #11: 0x0000000100003193 BeanCounter`-[AccountDocument configurePersistentStoreCoordinatorForURL:ofType:modelConfiguration:storeOptions:error:] + 419 at AccountDocument.m:298 

From what I can tell from the documentation, the default implementation looks something like this:

 - (id)managedObjectModel { NSManagedObjectModel *result = [NSManagedObjectModel mergedModelFromBundles:nil]; return result; } 

So, to debug the problem a bit more, I tried this method as follows:

 - (id)managedObjectModel { NSBundle *bundle = [NSBundle mainBundle]; NSURL *url = [bundle URLForResource:@"AccountDocument2" withExtension:@"momd"]; NSManagedObjectModel *result = [[[NSManagedObjectModel alloc] initWithContentsOfURL:url] autorelease]; return result; } 

(Thanks to Jeff Lamarsh for the idea: http://iphonedevelopment.blogspot.com/2009/09/core-data-migration-problems.html )

The bundle and url point to the places I expect (and I followed Marcus Zarra's advice to clear the project so that there are no wandering .mom or .momd packages in the application package: Using mergedModelFromBundles: and version control (CoreData) ). However, the application continues to crash when loading the model from the URL.

I checked that AccountDocument2.xcdatamodeld is a package that has two models for version control: AccountDocument 2.xcdatamodel and (original) AccountDocument.xcdatamodel. The Versioned Core Data Model pop-up menu in the file properties is set to AccountDocument 2.

The only difference between the two models is that one object has an additional (and optional) attribute. I understand that this model is suitable for lightweight migration.

Obviously, I am doing something wrong, but I have no idea what. Any help would be most appreciated ...

Update:

In Martin's suggestion (and checking the NSPsistentDocument documentation), I tried using this code for accessories:

 - (id)managedObjectModel { static id sharedManagedObjectModel = nil; if (sharedManagedObjectModel == nil) { NSBundle *bundle = [NSBundle mainBundle]; NSURL *url = [bundle URLForResource:@"AccountDocument2" withExtension:@"momd"]; sharedManagedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:url]; } return sharedManagedObjectModel; } 

Still crashing ...

Update

After some suggestions on Twitter, I upgraded to Xcode 4.3.2, but problems persist.

RAGE UPDATE

I just created a package with a model version (AccountDocument2.xcdatamodeld) using Xcode 4.2 on Snow Leopard. After you create and run the application, everything works as expected.

Then I took the AccountDocument2.xcdatamodeld package of files back to Lion and Xcode 4.3.2. When I create and run the application, it continues to crash when loading the .momd resource. Yes, children, that is, Xcode 4.3.x and the data model compiler (MOMC). I do not see a workaround, except to do all my builds on Snow Leopard.

I'm not one of the bash of Xcode 4, but when we find ourselves in a situation where the toolchain cannot create an opaque file (.mom and .momd) from an opaque specification (.xcdatamodel and .xcdatamodeld) it is quite difficult to be optimistic about the state of Mac and iOS. It is ridiculous that the main component of these platforms breaks down to such an extent that I cannot create and run my application in the latest version of the SDK and the developer tools.

Go to this update

Further evidence that this is a serious bug with the Data Model Compiler (MOMC) in Xcode 4.3.2: if I copy the .momd package from the resource folder created by Xcode 4.2 to my project and add them to the assembly as a build phase of the copy files The application is working fine.

I also conducted several tests where I removed the validation rules and default values ​​for the Attributes of various objects (based on Marcus's suggestion below). No change, the compiler still creates an invalid .momd. I also tried to create a version of the model in which nothing changed: the compiled .momd continued to fail. Thus, everything that you have in your current models (and the data that they represent) is the source of the problem.

Also note: this error is not isolated from NSPersistentDocument (as I thought when I started this question.) I can cause the application to crash simply by using [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL] .

I will currently be editing / versioning my models using Xcode 4.2 on Snow Leopard and moving compiled resources to Xcode 4.3.2 on Lion. If you use Core Data in any way, I suggest you do the same until this error is fixed. Believe me, you will spend days trying to understand what the hell happens if you do not.

Now to send the radar ...

Radar update

I just introduced this radar:

http://www.openradar.me/11184500

Oh my gosh it needs to be updated by a lion

I just downloaded and installed the Xcode 4.2 tools for Lion from http://developer.apple.com/downloads . The sample application used in the Radar is still crashing.

(Note: you cannot install Xcode 4.2.1 because the certificate used to sign DeveloperTools.pkg has expired. Only Xcode 4.2 will work.)

If you are under the NDA, you will also find that beta tools do not help either.

Hope you have a copy of Snow Leopard with Xcode 4.2 sitting around: http://furbo.org/2012/03/28/vmware-for-developers/

WTF Do Fetch requests should do with updated objects and attributes

Via Evadne Wu on Twitter:

https://twitter.com/#!/evadne/status/187625192342818818

And how she did it:

https://twitter.com/#!/evadne/status/187629091518816258

(.Mm files are binary.)

The root of the problem is one select request. How does this affect the transfer of data from one model to another, for an Apple engineer to understand.

+45
objective-c cocoa core-data osx-lion nspersistentdocument
Apr 03 2018-12-12T00:
source share
4 answers

Compiled .momd resources can be loaded after changing the "existingPartner" fetch request:

 name == $name 

at

 name == $name 

This contradicts the fact that the part of the object model that does not affect the persistence of data violates version control and facilitated migration. From the documentation it is clear that this should not be:

The prospect of Core Datas when versioning is that it is only interested in the features of the model that affect constancy.

Use CHOCKLOCK to fix your select queries or completely delete them and rely on NSPredicates created in the code .

+11
Apr 04 2018-12-12T00:
source share

I think you need to save the managed model of the object in an instance variable. You are returning an auto-implemented object, which is likely to cause poor access.

+1
Apr 03 '12 at 20:50
source share

Based on your theory that this is a problem with MOMC, do you have any validation rules in mom?

I saw reports in which validation rules do not withstand 4.x MOMC.

+1
Apr 04 2018-12-12T00:
source share

This may be due to a problem that I encountered using select queries when iOS5 first came out in beta. This caused a crash warning and caused the application to crash on startup. I did not use a fetch request, so I deleted it and everything worked fine: Warning about basic data: "Hash version information is not available for all models"

0
Apr 05 '12 at 8:14
source share



All Articles