I have a situation where I am doing a post of an object (not a managed one, just an NSObject derived one), but the response from the REST API is not a JSON representation of the kind of object being posted. It is something else altogether. Is it possible to handle this?
Say I post an object (JSON):
{
"prop1" : 123,
"prop2" : 5
}
And the response if not an object with properties prop1
and prop2
, as RestKit expects by default, but something else:
{
"data" : [1,2,3,4,5,6],
"message" : "hello world"
}
I've seen examples where operation.targetObject was set to nil, but (I believe) this is only in Core Data managed scenarios.
I am trying something simple like this:
RKObjectRequestOperation *operation = [self.objectManager appropriateObjectRequestOperationWithObject:body method:RKRequestMethodPOST path:@"items" parameters:nil];
[operation setCompletionBlockWithSuccess:^(RKObjectRequestOperation *operation, RKMappingResult *result) {
// success is called, but the result does not contain what the response JSON is
} failure:^(RKObjectRequestOperation *operation, NSError *error) {
// failure
}];
[operation setWillMapDeserializedResponseBlock:^id(id deserializedResponseBody) {
// deserializedResponseBody is always nil
}];
[operation start];
I thought I could be able to look at the response contents in the setWillMapDeserializedResponseBlock, but it is always nil.
Because the posted object has prop1
and prop2
properties, and how RestKit works by default, it expects JSON with said properties. But, since the result has nothing to do with the posted object, prop1
and prop2
are just nil (which I don't care for anyway).
By the way, I have setup the request mapping correctly, so the body
being passes in the operation object is correctly mapping my NSObject and sending it in the correct JSON format to the server.
Is there a way that I can make such a call with RestKit, and manually pull out what I am looking for on the success event? Even if it was a dictionary representation of the JSON response?
You can convert the source object into a dictionary and send that instead. Then the response data will naturally be mapped into a dictionary. This should be a minimal change to your mappings and a small change to the other code (using KVC dictionaryWithValuesForKeys:
).
I'd just create a new object for your response and map your response to that.
@interface MYRequest : NSObject
@property NSNumber *prop1;
@property NSNumber *prop2;
@end
@interface MYResponse : NSObject
@property NSArray *data;
@property NSString *message;
@end
RKObjectMapping *requestMapping = [RKObjectMapping requestMapping];
[requestMapping addAttributeMappingsFromArray:@[@"prop1", @"prop2"]];
RKObjectMapping *responseMapping = [RKObjectMapping mappingForClass:[MYResponse class]];
[requestMapping addAttributeMappingsFromArray:@[@"data", @"message"]];
RKRequestDescriptor *requestDescriptor = [RKRequestDescriptor requestDescriptorWithMapping:requestMapping
objectClass:[MYRequest class]
rootKeyPath:nil
method:RKRequestMethodPOST];
RKResponseDescriptor *responseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:responseMapping
method:RKRequestMethodPOST
pathPattern:@"items"
keyPath:nil
statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)];
[self.objectManager addRequestDescriptor:requestDescriptor];
[self.objectManager addResponseDescriptor:responseDescriptor];
MYRequest *body = [MYRequest new];
[body setProp1:@123];
[body setProp2:@5];
[self.objectManager postObject:body
path:@"items"
parameters:nil
success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
MYResponse *result = [mappingResult firstObject];
NSLog(@"Data: %@\nMessage: %@", [result data], [result message]);
}
failure:^(RKObjectRequestOperation *operation, NSError *error) {
NSLog(@"Error: %@", error);
}];
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