I have a NSPersistentDocument
with a given Core Data model, etc.
I have a file, created by this document, let's say it its preload.xml. It "contains" several NSManagedObject
s.
I would like to load these objects in all my new documents, so that when I create a new document, the new document automatically "has" the objects "living" in preload.xml. So far, here is what I did :
I copied preload.xml
in my project.
In the initWithType:error:
method (the method called when a new document is created), have the following code :
NSURL *preloadURL = [NSURL fileURLWithPath:[[NSBundle mainBundle]
pathForResource:@"preload"
ofType:@"xml"]];
NSError* err = nil;
[self readFromURL:preloadURL
ofType:@"xml"
error:&err] ;
This doesn't work because, when I try afterwards to save my document to, let's say myNewDoc.xml
, this file is empty but all my new data is saved to preload.xml
.
I am wondering if I need to create a new store
or context
or storeCoordinator
or something else. I never dealt with such objects since I always used NSPersistentDocument
.
Get the saved objects :
NSPersistentStoreCoordinator * newPersStoreCoord ;
newPersStoreCoord = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:theDoc.managedObjectModel] ;
NSString * path = [[NSBundle mainBundle] pathForResource:@"preload"
ofType:@"xml"];
NSURL *preloadURL = [NSURL fileURLWithPath:path];
[newPersStoreCoord addPersistentStoreWithType:NSBinaryStoreType
configuration:nil
URL:preloadURL
options:nil
error:NULL] ;
NSManagedObjectContext * auxMOC = [[NSManagedObjectContext alloc] init] ;
[auxMOC setPersistentStoreCoordinator:newPersStoreCoord] ;
copy them to your "living" MOC
[self loadPreloadedDataFromTheMOC:auxMOC
toTheMOC:theDoc.managedObjectContext
forTheDoc:theDoc] ;
with the help of cloning techniques
- (NSManagedObject *)cloneInContext:(NSManagedObjectContext *)context
withCopiedCache:(NSMutableDictionary *)alreadyCopied
exludeEntities:(NSArray *)namesOfEntitiesToExclude
excludeAttributes:(NSArray *)namesOfAttributesToExclude
{
NSString *entityName = [[self entity] name];
if ([namesOfEntitiesToExclude containsObject:entityName])
{
return nil;
}
NSManagedObject *cloned = [alreadyCopied objectForKey:[self objectID]];
if (cloned != nil)
{
return cloned;
}
//create new object in data store
cloned = [NSEntityDescription insertNewObjectForEntityForName:entityName
inManagedObjectContext:context];
[alreadyCopied setObject:cloned
forKey:[self objectID]];
//loop through all attributes and assign then to the clone
NSDictionary *attributes = [[NSEntityDescription entityForName:entityName
inManagedObjectContext:context] attributesByName];
for (NSString *attr in attributes)
{
if (![namesOfAttributesToExclude containsObject:attr])
{
[cloned setValue:[self valueForKey:attr] forKey:attr];
}
}
//Loop through all relationships, and clone them.
NSDictionary *relationships = [[NSEntityDescription entityForName:entityName
inManagedObjectContext:context] relationshipsByName];
for (NSString *relName in [relationships allKeys])
{
NSRelationshipDescription *rel = [relationships objectForKey:relName];
NSString *keyName = rel.name;
if ([rel isToMany])
{
id sourceSet ;
id clonedSet ;
/*
On gère selon que la relation est ordonnée ou non
*/
if (![rel isOrdered])
{
//get a set of all objects in the relationship
sourceSet = [self mutableSetValueForKey:keyName];
clonedSet = [cloned mutableSetValueForKey:keyName];
}
else
{
sourceSet = [self mutableOrderedSetValueForKey:keyName];
clonedSet = [cloned mutableOrderedSetValueForKey:keyName];
}
NSEnumerator *e = [sourceSet objectEnumerator];
NSManagedObject *relatedObject;
while (relatedObject = [e nextObject])
{
//Clone it, and add clone to set
NSManagedObject *clonedRelatedObject = [relatedObject cloneInContext:context
withCopiedCache:alreadyCopied
exludeEntities:namesOfEntitiesToExclude
excludeAttributes:namesOfAttributesToExclude];
if (clonedRelatedObject)
{
[clonedSet addObject:clonedRelatedObject];
}
}
}
else
{
NSManagedObject *relatedObject = [self valueForKey:keyName];
if (relatedObject != nil)
{
NSManagedObject *clonedRelatedObject = [relatedObject cloneInContext:context
withCopiedCache:alreadyCopied
exludeEntities:namesOfEntitiesToExclude
excludeAttributes:namesOfAttributesToExclude];
if (clonedRelatedObject)
{
[cloned setValue:clonedRelatedObject forKey:keyName];
}
}
}
}
return cloned;
}