Skip to content

Instantly share code, notes, and snippets.

@weejayuk
Forked from vl4dimir/ExtendedManagedObject.h
Created October 5, 2010 07:16
Show Gist options
  • Select an option

  • Save weejayuk/611157 to your computer and use it in GitHub Desktop.

Select an option

Save weejayuk/611157 to your computer and use it in GitHub Desktop.
typedef BOOL (^BlockingRelationship)(id,NSString*);
@interface NSManagedObject (ExtendedManagedObject)
- (NSDictionary*) toDictionaryBlockingRelationships:(BOOL (^)(id obj,NSString *relationship))blockRelationship;
+ (NSManagedObject*) createManagedObjectFromDictionary:(NSDictionary*)dict
inContext:(NSManagedObjectContext*)context;
@end
#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
//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);
}
@wryphonedev
Copy link
Copy Markdown

Thanks. Yeah compiling with LLVM works fine.

@weejayuk
Copy link
Copy Markdown
Author

weejayuk commented Jun 27, 2011 via email

Copy link
Copy Markdown

ghost commented Apr 23, 2012

Just updating about the fix that can be found here: http://stackoverflow.com/questions/6503823/compilation-issue-when-using-blocks-with-llvm-gcc-4-2

Change

BlockingRelationship blockRelationship=^BOOL(id obj,NSString* relationship)){

to

BOOL (^blockRelationship)(id,NSString_)=^(id obj,NSString_ relationship) {

@ExoticObjects
Copy link
Copy Markdown

Extremely helpful. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment