How to NSKeyedUnarchive subclasses of NSManagedObj

2019-08-08 11:56发布

问题:

An existing document based application that saves and loads it's data using NSKeyedArchiver/NSKeyedUnarchiver is currently transformed to use Core Data as it's storage backend.

Now I am trying to have a kind of import of files saved using the former application. The object structure didn't change, but I changed all objects to be NSManagedObjects. Now the initWithCoder: calls [super initWithCoder:] and doesn't create the object using NSEntityDescription. That failes epically (as expected).

My question is: what is the best practice / a good advice to have such an import functionality?

回答1:

The correct way would be to implement a subclass of NSAtomicStore that unarchives the old data format into a Core Data representation. After loading the old data using that store, you can easily migrate the data using -[NSPersistentStoreCoordinator migratePersistentStore:toURL:options:withType:NSSQLiteStoreType error:]

OLD (WRONG) ANSWER:

After fiddeling together my own solution (with some banging-head-on-desk involved) I found the same solution described by The Mental Faculty:

KEYED-ARCHIVING TO CORE DATA MIGRATION

I did it the same way they do, but I created my own subclass of NSKeyedValueDecoder that stores the context. The initWithCoder: of my CBManagedObject superclass to all entities looks like this:

- (id) initWithCoder:(NSCoder *)inCoder {
    NSManagedObjectContext *context = ((CBNSKeyedUnarchiverCoreData*)inCoder).context;
    self = [super initWithEntity:[NSEntityDescription entityForName:[[self class] entityName] 
                                             inManagedObjectContext:context] insertIntoManagedObjectContext:context];
    if (!self) return nil;
    return self;
}

Each entity gives his entity name with the class method +entityName.

Seems like a good solution as it works very good by now.