Skip to content

Commit

Permalink
Fix for #709 - [RKManagedObjectThreadSafeInvocation serializeManagedO…
Browse files Browse the repository at this point in the history
…bjectsForArgument:withKeyPaths:] is not properly serializing managed objects

Fixed RKManagedObjectThreadSafeInvocation to properly handle serialization when the key is a keyPath.

Updated RKManagedObjectThreadSafeInvocationTest to test keyPath keys.
  • Loading branch information
Eric Chamberlain authored and blakewatters committed May 19, 2012
1 parent f585d34 commit 01607a9
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 5 deletions.
22 changes: 17 additions & 5 deletions Code/CoreData/RKManagedObjectThreadSafeInvocation.m
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,24 @@ - (void)setManagedObjectKeyPaths:(NSSet*)keyPaths forArgument:(NSInteger)index {
[_argumentKeyPaths setObject:keyPaths forKey:argumentIndex];
}

- (void)setValue:(id)value forKeyPathOrKey:(NSString *)keyPath object:(id)object {
[object setValue:value forKeyPath:keyPath];

id testValue = [object valueForKeyPath:keyPath];
if (![value isEqual:testValue]) {
[object setValue:value forKey:keyPath];
testValue = [object valueForKeyPath:keyPath];

NSAssert([value isEqual:testValue], @"Could not set value");
}
}

- (void)serializeManagedObjectsForArgument:(id)argument withKeyPaths:(NSSet*)keyPaths {
for (NSString* keyPath in keyPaths) {
id value = [argument valueForKeyPath:keyPath];
if ([value isKindOfClass:[NSManagedObject class]]) {
[argument setValue:[(NSManagedObject*)value objectID] forKeyPath:keyPath];
NSManagedObjectID *objectID = [(NSManagedObject*)value objectID];
[self setValue:objectID forKeyPathOrKey:keyPath object:argument];
} else if ([value respondsToSelector:@selector(allObjects)]) {
id collection = [[[[[value class] alloc] init] autorelease] mutableCopy];
for (id subObject in value) {
Expand All @@ -52,7 +65,7 @@ - (void)serializeManagedObjectsForArgument:(id)argument withKeyPaths:(NSSet*)key
}
}

[argument setValue:collection forKeyPath:keyPath];
[self setValue:collection forKeyPathOrKey:keyPath object:argument];
[collection release];
}
}
Expand All @@ -65,7 +78,7 @@ - (void)deserializeManagedObjectIDsForArgument:(id)argument withKeyPaths:(NSSet*
NSAssert(self.objectStore, @"Object store cannot be nil");
NSManagedObject* managedObject = [self.objectStore objectWithID:(NSManagedObjectID*)value];
NSAssert(managedObject, @"Expected managed object for ID %@, got nil", value);
[argument setValue:managedObject forKeyPath:keyPath];
[self setValue:managedObject forKeyPathOrKey:keyPath object:argument];
} else if ([value respondsToSelector:@selector(allObjects)]) {
id collection = [[[[[value class] alloc] init] autorelease] mutableCopy];
for (id subObject in value) {
Expand All @@ -78,12 +91,11 @@ - (void)deserializeManagedObjectIDsForArgument:(id)argument withKeyPaths:(NSSet*
}
}

[argument setValue:collection forKeyPath:keyPath];
[self setValue:collection forKeyPathOrKey:keyPath object:argument];
[collection release];
}
}
}

- (void)serializeManagedObjects {
for (NSNumber* argumentIndex in _argumentKeyPaths) {
NSSet* managedKeyPaths = [_argumentKeyPaths objectForKey:argumentIndex];
Expand Down
14 changes: 14 additions & 0 deletions Tests/Logic/CoreData/RKManagedObjectThreadSafeInvocationTest.m
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,20 @@ - (void)testShouldSerializeOneManagedObjectToManagedObjectID {
assertThat([dictionary valueForKeyPath:@"human"], is(instanceOf([NSManagedObjectID class])));
}

- (void)testShouldSerializeOneManagedObjectWithKeyPathToManagedObjectID {
NSString *testKey = @"data.human";
RKManagedObjectStore* objectStore = [RKTestFactory managedObjectStore];
RKObjectManager *objectManager = [RKTestFactory objectManager];
objectManager.objectStore = objectStore;
RKHuman* human = [RKHuman object];
NSMutableDictionary* dictionary = [NSMutableDictionary dictionaryWithObject:human forKey:testKey];
NSMethodSignature* signature = [self methodSignatureForSelector:@selector(informDelegateWithDictionary:)];
RKManagedObjectThreadSafeInvocation* invocation = [RKManagedObjectThreadSafeInvocation invocationWithMethodSignature:signature];
[invocation serializeManagedObjectsForArgument:dictionary withKeyPaths:[NSSet setWithObject:testKey]];
assertThat([dictionary valueForKeyPath:testKey], is(instanceOf([NSManagedObjectID class])));
}


- (void)testShouldSerializeCollectionOfManagedObjectsToManagedObjectIDs {
RKManagedObjectStore* objectStore = [RKTestFactory managedObjectStore];
RKObjectManager *objectManager = [RKTestFactory objectManager];
Expand Down

0 comments on commit 01607a9

Please sign in to comment.