Don't generate an unmappable content error if a successful status code is returned along with an empty response body. This enables the use of the status code to indicate success without any content for mapping. In these cases, we wrap the targetObject of the loader into a RKObjectMappingResult at the @"" keyPath so that the delegates are invoked as expected. closes #189

This commit is contained in:
Blake Watters
2011-07-06 22:01:10 -04:00
parent 42067b9036
commit c171bed7d3
9 changed files with 111 additions and 10 deletions

View File

@@ -46,6 +46,11 @@
*/
- (void)objectLoader:(RKObjectLoader*)objectLoader didLoadObjectDictionary:(NSDictionary*)dictionary;
/**
Invoked when the object loader has finished loading
*/
- (void)objectLoaderDidFinishLoading:(RKObjectLoader*)objectLoader;
/**
Sent when an object loader encounters a response status code it does not know how to handle.
2xx, 4xx, and 5xx responses are all handled appropriately. This should only occur when the remote

View File

@@ -85,6 +85,10 @@
if (successful) {
_isLoaded = YES;
if ([self.delegate respondsToSelector:@selector(objectLoaderDidFinishLoading:)]) {
[(NSObject<RKObjectLoaderDelegate>*)self.delegate objectLoaderDidFinishLoading:self];
}
NSDictionary* userInfo = [NSDictionary dictionaryWithObject:_response
forKey:RKRequestDidLoadResponseNotificationUserInfoResponseKey];
[[NSNotificationCenter defaultCenter] postNotificationName:RKRequestDidLoadResponseNotification
@@ -145,7 +149,21 @@
- (RKObjectMappingResult*)mapResponseWithMappingProvider:(RKObjectMappingProvider*)mappingProvider toObject:(id)targetObject error:(NSError**)error {
id<RKParser> parser = [[RKParserRegistry sharedRegistry] parserForMIMEType:self.response.MIMEType];
NSAssert1(parser, @"Cannot perform object load without a parser for MIME Type '%@'", self.response.MIMEType);
id parsedData = [parser objectFromString:[self.response bodyAsString] error:error];
// Check that there is actually content in the response body for mapping. It is possible to get back a 200 response
// with the appropriate MIME Type with no content (such as for a successful PUT or DELETE). Make sure we don't generate an error
// in these cases
id bodyAsString = [self.response bodyAsString];
if (bodyAsString == nil || [[bodyAsString stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]] length] == 0) {
RKLogDebug(@"Mapping attempted on empty response body...");
if (self.targetObject) {
return [RKObjectMappingResult mappingResultWithDictionary:[NSDictionary dictionaryWithObject:self.targetObject forKey:@""]];
}
return nil;
}
id parsedData = [parser objectFromString:bodyAsString error:error];
if (parsedData == nil && error) {
return nil;
}
@@ -204,8 +222,11 @@
_result = [[self performMapping:&error] retain];
if (self.result) {
[self processMappingResult:self.result];
} else {
} else if (error) {
[self performSelectorInBackground:@selector(didFailLoadWithError:) withObject:error];
} else {
// A nil response with an error indicates success, but no mapping results
[self finalizeLoad:YES error:nil];
}
[pool drain];