Import and export an NSManagedObject hierarchy

I am at startup to make my NSMangedObjectClass profile im- / exportable.
I will try this way
Exporting works correctly if I write relationships in NSArrays because NSSet does not have writeToFile .

 - (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 you want to import on the other hand

 - (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 does not confuse me, because Profile expects NSSet and 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'

Therefore, I have two problems:

  • For one thing, I cannot write NSSet for a file.
  • On the other hand, my profile class expects NSSet.

So, I tried to create an NSSet category that 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 are not called.

Is there any other way to write my NSSet or tell setValuesForKeysWithDictionary "Views" Key is an NSArray?

Or an easy way to import or export ManagedObjects?

+4
source share
2 answers

You have problems with nested NSDictonarys, so I said goodbye to the dynamic way. Here is my complete solution to help others
ViewController to call 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 have 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 yet to figure out how to avoid duplicates in my n: m connection

thanks

+2
source

Can you try to override the default implementation of NSManagedObject for setValuesForKeysWithDictionary?

Looking at the documentation , you only need to implement setValue: forKey: in your subclasses?

You have to grab NSSet there and deal with it yourself before the exception is thrown?

[Disclaimer - I never did that!]

+1
source

Source: https://habr.com/ru/post/1347573/


All Articles