mirror of
https://github.com/zhigang1992/RestKit.git
synced 2026-01-12 22:51:50 +08:00
Intelligently set the targetObject by exploring the mapping graph in appropriateObjectRequestOperationWithObject: to better support cases in which you POST/PUT one object, but map back another. fixes #1081
This commit is contained in:
@@ -169,6 +169,34 @@ static BOOL RKDoesArrayOfResponseDescriptorsContainEntityMapping(NSArray *respon
|
||||
return NO;
|
||||
}
|
||||
|
||||
static BOOL RKDoesArrayOfResponseDescriptorsContainMappingForClass(NSArray *responseDescriptors, Class classToBeMapped)
|
||||
{
|
||||
// Visit all mappings accessible from the object graphs of all response descriptors
|
||||
NSMutableSet *accessibleMappings = [NSMutableSet set];
|
||||
for (RKResponseDescriptor *responseDescriptor in responseDescriptors) {
|
||||
if (! [accessibleMappings containsObject:responseDescriptor.mapping]) {
|
||||
RKMappingGraphVisitor *graphVisitor = [[RKMappingGraphVisitor alloc] initWithMapping:responseDescriptor.mapping];
|
||||
[accessibleMappings unionSet:graphVisitor.mappings];
|
||||
}
|
||||
}
|
||||
|
||||
// Enumerate all mappings and search for a mapping matching the class
|
||||
for (RKMapping *mapping in accessibleMappings) {
|
||||
if ([mapping isKindOfClass:[RKObjectMapping class]]) {
|
||||
if ([[(RKObjectMapping *)mapping objectClass] isSubclassOfClass:classToBeMapped]) return YES;
|
||||
}
|
||||
|
||||
if ([mapping isKindOfClass:[RKDynamicMapping class]]) {
|
||||
RKDynamicMapping *dynamicMapping = (RKDynamicMapping *)mapping;
|
||||
for (RKObjectMapping *mapping in dynamicMapping.objectMappings) {
|
||||
if ([[(RKObjectMapping *)mapping objectClass] isSubclassOfClass:classToBeMapped]) return YES;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NO;
|
||||
}
|
||||
|
||||
static NSString *RKMIMETypeFromAFHTTPClientParameterEncoding(AFHTTPClientParameterEncoding encoding)
|
||||
{
|
||||
switch (encoding) {
|
||||
@@ -419,7 +447,7 @@ static NSString *RKMIMETypeFromAFHTTPClientParameterEncoding(AFHTTPClientParamet
|
||||
operation = [self objectRequestOperationWithRequest:request success:nil failure:nil];
|
||||
}
|
||||
|
||||
operation.targetObject = object;
|
||||
if (RKDoesArrayOfResponseDescriptorsContainMappingForClass(self.responseDescriptors, [object class])) operation.targetObject = object;
|
||||
return operation;
|
||||
}
|
||||
|
||||
|
||||
@@ -574,6 +574,28 @@
|
||||
expect([manager.baseURL absoluteString]).to.equal(@"http://google.com/");
|
||||
}
|
||||
|
||||
- (void)testPostingOneObjectAndGettingResponseMatchingAnotherClass
|
||||
{
|
||||
RKObjectManager *manager = [RKObjectManager managerWithBaseURL:[RKTestFactory baseURL]];
|
||||
RKObjectMapping *userMapping = [RKObjectMapping mappingForClass:[RKTestUser class]];
|
||||
[userMapping addAttributeMappingsFromDictionary:@{ @"fullname": @"name" }];
|
||||
RKObjectMapping *metaMapping = [RKObjectMapping mappingForClass:[NSMutableDictionary class]];
|
||||
[metaMapping addAttributeMappingsFromArray:@[ @"status", @"version" ]];
|
||||
RKResponseDescriptor *metaResponseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:metaMapping pathPattern:nil keyPath:@"meta" statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)];
|
||||
|
||||
[manager addResponseDescriptorsFromArray:@[ metaResponseDescriptor ]];
|
||||
RKTestUser *user = [RKTestUser new];
|
||||
RKObjectRequestOperation *requestOperation = [manager appropriateObjectRequestOperationWithObject:user method:RKRequestMethodPOST path:@"/ComplexUser" parameters:nil];
|
||||
[requestOperation start];
|
||||
[requestOperation waitUntilFinished];
|
||||
|
||||
expect(requestOperation.error).to.beNil();
|
||||
expect(requestOperation.mappingResult).notTo.beNil();
|
||||
expect([requestOperation.mappingResult array]).to.haveCountOf(1);
|
||||
NSDictionary *expectedObject = @{ @"status": @"ok", @"version": @"0.3" };
|
||||
expect([requestOperation.mappingResult firstObject]).to.equal(expectedObject);
|
||||
}
|
||||
|
||||
- (void)testPostingOneObjectAndGettingResponseMatchingMultipleDescriptors
|
||||
{
|
||||
RKObjectManager *manager = [RKObjectManager managerWithBaseURL:[RKTestFactory baseURL]];
|
||||
|
||||
Reference in New Issue
Block a user