I'm on the run to make my NSMangedObjectClass profile im-/exportable.
I try it this way
Exporting works correctly if I write the Relationships in NSArrays because NSSet doesn't have writeToFile
implemented.
- (void) exportProfile:(Profile *)profile toPath:(NSString *)path{
//Profile
NSMutableDictionary *profileDict = [[self.selectedProfile dictionaryWithValuesForKeys:[[[self.selectedProfile entity] attributesByName] allKeys]] mutableCopy];
NSMutableArray *views = [NSMutableArray array];
//Views
for (View *view in selectedProfile.views) {
NSMutableDictionary *viewDict = [[view dictionaryWithValuesForKeys:[[[view entity] attributesByName] allKeys]] mutableCopy];
NSMutableArray *controls = [NSMutableArray array];
//Much more for-loops
[viewDict setObject:controls forKey:@"controls"];
[views addObject:viewDict];
}
[profileDict setObject:views forKey:@"views"];
if([profileDict writeToFile:[path stringByStandardizingPath] atomically:YES])
NSLog(@"Saved");
else
NSLog(@"Not saved");
[profileDict release];
}
But if want to import on the other side
- (Profile*) importProfileFromPath:(NSString *)path{
NSManagedObjectContext *context = [self.fetchedResultsController managedObjectContext];
Profile *newProfile = [NSEntityDescription insertNewObjectForEntityForName:@"Profile" inManagedObjectContext:context];
NSMutableDictionary *profileDict = [NSMutableDictionary dictionaryWithContentsOfFile:[path stringByStandardizingPath]];
[newProfile setValuesForKeysWithDictionary:profileDict];
}
I get an exception, this doesn't confuse me cause Profile expects a NSSet and no NSArray.
[__NSCFArray intersectsSet:]: unrecognized selector sent to instance 0x4e704c0 *** Terminating app due to uncaught exception 'NSInvalidArgumentException',
reason: '-[__NSCFArray intersectsSet:]: unrecognized selector sent to instance 0x4e704c0'
So I've got two problems:
So I tried to create a Category of NSSet which implements writeToFile
@implementation NSSet(Persistence)
- (BOOL)writeToFile:(NSString*)path atomically:(BOOL)flag{
NSMutableArray *temp = [NSMutableArray arrayWithCapacity:self.count];
for(id element in self)
[temp addObject:element];
return [temp writeToFile:path atomically:flag];
}
+ (id)setWithContentsOfFile:(NSString *)aPath{
return [NSSet setWithArray:[NSArray arrayWithContentsOfFile:aPath]];
}
@end
But my functions aren't called.
Is there a other way to write my NSSet or tell setValuesForKeysWithDictionary
the Key "views" is a NSArray?
Or a easy Way to im-/export ManagedObjects?
Got problems with the nested NSDictonarys, so i said goodbye to the dynamic way.
Here is my complete Solution to help others
ViewController to call the im/export functions
- (void) exportProfile:(Profile *)profile toPath:(NSString *)path{
//Call the NSManagedobject function to export
NSDictionary *profileDict = [self.selectedProfile dictionaryForExport];
if([profileDict writeToFile:[path stringByStandardizingPath] atomically:YES])
NSLog(@"Saved");
else
NSLog(@"Not saved");
}
- (void) importProfileFromPath:(NSString *)path{
NSManagedObjectContext *context = [self.fetchedResultsController managedObjectContext];
Profile *newProfile = [NSEntityDescription insertNewObjectForEntityForName:@"Profile" inManagedObjectContext:context];
//load dictonary from file
NSMutableDictionary *profileDict = [NSMutableDictionary dictionaryWithContentsOfFile:[path stringByStandardizingPath]];
//call the NSManagedObjects import function
[newProfile importWithDictonary:profileDict context:context];
NSError *error = nil;
if (![context save:&error]) {
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
}
NSManagedObject functions i got a hierarchy so i put them in each of my NSManagedObjects
- (void) importWithDictonary:(NSDictionary*)dict context:(NSManagedObjectContext*)context{
self.name = [dict objectForKey:@"name"];
//Relationship
for (NSDictionary *view in [dict objectForKey:@"views"]) {
View *tempView = [NSEntityDescription insertNewObjectForEntityForName:@"View" inManagedObjectContext:context];
[tempView importWithDictonary:view context:context];
tempView.profile = self;
[self addViewsObject:tempView];
}
}
- (NSDictionary*) dictionaryForExport{
//propertys
NSMutableDictionary *dict = [[[self dictionaryWithValuesForKeys:[[[self entity] attributesByName] allKeys]] mutableCopy] autorelease];
NSURL *objectID = [[self objectID] URIRepresentation];
[dict setObject: [objectID absoluteString] forKey:@"objectID"];
NSMutableArray *views = [NSMutableArray array];
//relationship
for (View *view in self.views) {
[views addObject:[view dictionaryForExport]];
}
[dict setObject:views forKey:@"views"];
return dict;
}
not the most beautiful solution but it works :)
and i have still to figure out how to avoid duplicates in my n:m relationship
Thanks