I'm having trouble mapping a response back to an object during a post request using RestKit.
Here's the code:
Request:
// mapping for the response. response is an object: {"response":"message","success":bool}
RKObjectMapping *responseMapping = [RKObjectMapping mappingForClass:[GenericResponse class]];
[responseMapping addAttributeMappingsFromArray:@[@"success",@"response"]];
responseMapping.setDefaultValueForMissingAttributes = YES;
RKResponseDescriptor *responseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:responseMapping pathPattern:@"/authenticate" keyPath:nil statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)];
// mapping for the request body
RKObjectMapping *requestMapping = [RKObjectMapping requestMapping];
[requestMapping addAttributeMappingsFromArray:@[@"username", @"password"]];
RKRequestDescriptor *requestDescriptor = [RKRequestDescriptor requestDescriptorWithMapping:requestMapping objectClass:[LoginCriteria class] rootKeyPath:nil];
// set up the request
RKObjectManager *manager = [RKObjectManager managerWithBaseURL:[NSURL URLWithString:@"http://localhost:8080"]];
[manager addResponseDescriptor:responseDescriptor];
[manager addRequestDescriptor:requestDescriptor];
[manager setRequestSerializationMIMEType:@"application/json"];
// set up the LoginCriteria object
LoginCriteria* loginCriteria = [LoginCriteria new];
loginCriteria.password = @"test";
loginCriteria.username = @"test";
// make the request
[manager postObject:loginCriteria path:@"/authenticate" parameters:nil
success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
GenericResponse *genericResponse = (GenericResponse*)mappingResult;
NSLog(@"logged in: %@", [mappingResult array]);
} failure:^(RKObjectRequestOperation *operation, NSError *error) {
NSLog(@"login failed");
}];
GenericResponse.h:
@interface GenericResponse : NSObject
@property (nonatomic) Boolean* success;
@property (nonatomic, copy) NSString* response;
@end
Log:
2012-12-17 15:44:22.890 Radiuus[8221:1703] T restkit.network:RKHTTPRequestOperation.m:139 POST 'http://localhost:8080/authenticate':
request.headers={
Accept = "application/json";
"Accept-Language" = "en, fr, de, ja, nl, it, es, pt, pt-PT, da, fi, nb, sv, ko, zh-Hans, zh-Hant, ru, pl, tr, uk, ar, hr, cs, el, he, ro, sk, th, id, ms, en-GB, ca, hu, vi, en-us;q=0.8";
"Content-Type" = "application/json; charset=utf-8";
"User-Agent" = "Radiuus/1.0 (iPhone Simulator; iOS 6.0; Scale/1.00)";
}
request.body=(null)
2012-12-17 15:44:23.244 Radiuus[8221:5d0b] T restkit.network:RKHTTPRequestOperation.m:156 POST 'http://localhost:8080/authenticate' (200):
response.headers={
"Content-Type" = "application/json";
Date = "Mon, 17 Dec 2012 20:44:23 GMT";
Server = "Apache-Coyote/1.1";
"Transfer-Encoding" = Identity;
}
response.body={"response":"authentication succeeded","success":true}
2012-12-17 15:44:23.246 Radiuus[8221:4f03] W restkit.object_mapping:RKMapperOperation.m:76 Adding mapping error: Expected an object mapping for class of type 'LoginCriteria', provider returned one for 'GenericResponse'
From the log, what's strange to me is that it seems that RestKit is expecting to deserialize the response to a LoginCriteria object, but is "failing" when it is correctly getting a GenericResponse object instead, which is of course correct.
Any help is greatly appreciated!
Thanks for your answer to your question, as it lead me in the right direction to figure out how to use one of RestKit's built-in methods to solve this issue instead of modifying the core code.
From his documentation, https://github.com/RestKit/RestKit/wiki/Object-mapping, in the Handling Multiple Root Objects in Core Data Post/Put section, he mentions that if you want to post one type of object, but receive another in the response, then you have to nil
out the targetObject
in the request operation. A full example is missing from his documentation, so here is the block of code I used:
RKManagedObjectRequestOperation *operation = [RKObjectManager.sharedManager appropriateObjectRequestOperationWithObject: objectToBePOSTed method:RKRequestMethodPOST path: path parameters: params];
operation.targetObject = nil;
[operation setCompletionBlockWithSuccess:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
//handle success
} failure:^(RKObjectRequestOperation *operation, NSError *error) {
//handle failure
}];
[RKObjectManager.sharedManager enqueueObjectRequestOperation:operation];
~ Happy Holidays
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With