RestKit response cannot be deserialized for object

I am having trouble displaying the response to an object during an email request using RestKit.

Here is 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, which is strange for me, it seems that RestKit expects to deserialize the response to the LoginCriteria object, but "does not work" when it correctly receives the GenericResponse object, which, of course, is correct.

Any help is much appreciated!

+7
source share
3 answers

Thanks for your answer to your question, as it leads me in the right direction to figure out how to use one of the built-in RestKit methods to solve this problem, and not to change the kernel code.

From his documentation https://github.com/RestKit/RestKit/wiki/Object-mapping in the Handling Multiple Root Objects section in the Master Data / Place column, he mentions that if you want to publish one type of object, but get the answer in answer, then you should nil output targetObject to the request operation. A complete example is missing from his documentation, so here is the code block that 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

+9
source

I had the same problem with RestKit. The solution was to add a mapping for the object that I sent as an answer.

0
source

I dug up the RestKit code and found the following snippet in mapObject in RKMapperOperation.m :

 if (NO == [[self.targetObject class] isSubclassOfClass:objectMapping.objectClass]) { if ([_mappingsDictionary count] == 1) { NSString *errorMessage = [NSString stringWithFormat: @"Expected an object mapping for class of type '%@', provider returned one for '%@'", NSStringFromClass([self.targetObject class]), NSStringFromClass(objectMapping.objectClass)]; [self addErrorWithCode:RKMappingErrorTypeMismatch message:errorMessage keyPath:keyPath userInfo:nil]; return nil; } else { // There is more than one mapping present. We are likely mapping secondary key paths to new objects destinationObject = [self objectWithMapping:mapping andData:mappableObject]; } } 

This first if checks that targetObject (the request object) has a class type that is in the hierarchy objectMapping.objectClass (response object). Since my request and response objects are different, this of course fails. I set a breakpoint on this line to prove it. Here is what is printed when I check:

 (lldb) po self.targetObject (id) $1 = 0x09fb54d0 <LoginCriteria: 0x9fb54d0> (lldb) po objectMapping.objectClass (Class) $2 = 0x00162c58 GenericResponse 

As you can see, they have different types, so if successful, the function returns nil, leaving the response unmapped. I just replaced return nil; on destinationObject = [self objectWithMapping:mapping andData:mappableObject]; and everything works as expected.

I am not happy with this decision, because I don’t feel that the author of RestKit is intended for messages to send and receive different objects. Therefore it is a hack. I leave this unanswered until a) I get a better solution, or b) the author of RestKit makes this change himself (or accepts mine :).

0
source

All Articles