-
-
Save weejayuk/611157 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
typedef BOOL (^BlockingRelationship)(id,NSString*); | |
@interface NSManagedObject (ExtendedManagedObject) | |
- (NSDictionary*) toDictionaryBlockingRelationships:(BOOL (^)(id obj,NSString *relationship))blockRelationship; | |
+ (NSManagedObject*) createManagedObjectFromDictionary:(NSDictionary*)dict | |
inContext:(NSManagedObjectContext*)context; | |
@end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#import "ExtendedManagedObject.h" | |
@implementation NSManagedObject (ExtendedManagedObject) | |
#pragma mark - | |
#pragma mark Dictionary conversion methods | |
- (NSDictionary*) toDictionaryBlockingRelationships:(BlockingRelationship) blockRelationship; | |
{ | |
NSArray* attributes = [[[self entity] attributesByName] allKeys]; | |
NSArray* relationships = [[[self entity] relationshipsByName] allKeys]; | |
NSMutableDictionary* dict = [NSMutableDictionary dictionaryWithCapacity: | |
[attributes count] + [relationships count] + 1]; | |
[dict setObject:[[self class] description] forKey:@"class"]; | |
for (NSString* attr in attributes) { | |
NSObject* value = [self valueForKey:attr]; | |
if (value != nil) { | |
[dict setObject:value forKey:attr]; | |
} | |
} | |
NSLog(@"Looking through relationships of %@",[self class]); | |
for (NSString* relationship in relationships) { | |
NSLog(@"Looking for relationship of %@",relationship); | |
if(!blockRelationship(self,relationship)){ | |
NSObject* value = [self valueForKey:relationship]; | |
if ([value isKindOfClass:[NSSet class]]) { | |
// To-many relationship | |
// The core data set holds a collection of managed objects | |
NSSet* relatedObjects = (NSSet*) value; | |
// Our set holds a collection of dictionaries | |
NSMutableSet* dictSet = [NSMutableSet setWithCapacity:[relatedObjects count]]; | |
for (NSManagedObject *relatedObject in relatedObjects) { | |
NSDictionary *returnedDict=[relatedObject toDictionaryBlockingRelationships:blockRelationship]; | |
if(returnedDict) | |
[dictSet addObject:returnedDict]; | |
} | |
if(dictSet) | |
[dict setObject:dictSet forKey:relationship]; | |
} | |
else if ([value isKindOfClass:[NSManagedObject class]]) { | |
// To-one relationship | |
NSDictionary *returnedDict=nil; | |
NSManagedObject* relatedObject = (NSManagedObject*) value; | |
returnedDict=[relatedObject toDictionaryBlockingRelationships:blockRelationship]; | |
if (returnedDict) | |
[dict setObject:returnedDict forKey:relationship]; | |
} | |
} | |
} | |
return dict; | |
// traversed=YES; | |
} | |
+ (NSManagedObject*) createManagedObjectFromDictionary:(NSDictionary*)dict | |
inContext:(NSManagedObjectContext*)context | |
{ | |
NSString* class = [dict objectForKey:@"class"]; | |
NSManagedObject* newObject = | |
(NSManagedObject*)[NSEntityDescription insertNewObjectForEntityForName:class | |
inManagedObjectContext:context]; | |
for (NSString* key in [dict allKeys]) { | |
if ([key isEqualToString:@"class"]) { | |
continue; | |
} | |
NSObject* value = [dict objectForKey:key]; | |
if ([value isKindOfClass:[NSDictionary class]]) { | |
// This is a to-one relationship | |
NSManagedObject* relatedObject = | |
[NSManagedObject createManagedObjectFromDictionary:(NSDictionary*)value | |
inContext:context]; | |
[newObject setValue:relatedObject forKey:key]; | |
} | |
else if ([value isKindOfClass:[NSSet class]]) { | |
// This is a to-many relationship | |
NSSet* relatedObjectDictionaries = (NSSet*) value; | |
// Get a proxy set that represents the relationship, and add related objects to it. | |
// (Note: this is provided by Core Data) | |
NSMutableSet* relatedObjects = [newObject mutableSetValueForKey:key]; | |
for (NSDictionary* relatedObjectDict in relatedObjectDictionaries) { | |
NSManagedObject* relatedObject = | |
[NSManagedObject createManagedObjectFromDictionary:relatedObjectDict | |
inContext:context]; | |
[relatedObjects addObject:relatedObject]; | |
} | |
} | |
else if (value != nil) { | |
// This is an attribute | |
[newObject setValue:value forKey:key]; | |
} | |
} | |
return newObject; | |
} | |
@end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//Set this up as you like. Based on you object model. In the model you have Tables and relationships. | |
//Pick the ones where you want the recursion to stop, and look for them in the block and return YES | |
// when you find them. | |
BlockingRelationship blockRelationship=^BOOL(id obj,NSString* relationship)){ | |
NSLog(@"Testing blockRelationship in %@",[obj class]); | |
BOOL preventRelationship=NO; | |
if ([obj isKindOfClass:NSClassFromString(@"TableA")]){ | |
if([relationship isEqualToString:@"activeParent"]|[relationship isEqualToString:@"relationshipA"]) | |
preventRelationship=YES; | |
} | |
else if ([obj isKindOfClass:NSClassFromString(@"TableB")]){ //block all relationships from here. | |
preventRelationship=YES; | |
} | |
else if ([obj isKindOfClass:NSClassFromString(@"TableC")]){ //block all relationships from here. | |
preventRelationship=YES; | |
} | |
else if ([obj isKindOfClass:NSClassFromString(@"TableD")]){ | |
if([relationship isEqualToString:@"aRelationship"]) //many to many - block back | |
preventRelationship=YES; | |
} | |
else if ([obj isKindOfClass:NSClassFromString(@"TableE")]){ | |
if([relationship isEqualToString:@"bRelationship"]|([relationship isEqualToString:@"cRelationship"])) | |
preventRelationship=YES; | |
} | |
else if ([obj isKindOfClass:NSClassFromString(@"TableF")]){ | |
preventRelationship=YES; | |
} | |
return preventRelationship; | |
}; | |
//this is test code..call to make the dictionary from the managed object. | |
NSDictionary *returnedDict=[YourNSObject toDictionaryBlockingRelationships:blockRelationship]; | |
NSLog(@"%@",returnedDict); | |
//create another object model from your NSDictionary. | |
YourNSObject *newObjects =(YourNSObject*)[YourNSObject createManagedObjectFromDictionary:returnedDict | |
inContext:YourNSObject.managedObjectContext]; | |
NSManagedObjectContext *context = templateVersion.managedObjectContext; | |
NSError *error = nil; | |
if (![context save:&error]) { | |
NSLog(@"think we might get here%@",error); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Extremely helpful. Thanks!