dbarros dbarros -4 years ago 106
Objective-C Question

Handle a POST response with RestKit that is not mapped to the POST object

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?

Answer Source

I'd just create a new object for your response and map your response to that.

Objects

@interface MYRequest : NSObject

@property NSNumber *prop1;
@property NSNumber *prop2;

@end

@interface MYResponse : NSObject

@property NSArray *data;
@property NSString *message;

@end

Mappings

RKObjectMapping *requestMapping = [RKObjectMapping requestMapping];
[requestMapping addAttributeMappingsFromArray:@[@"prop1", @"prop2"]];

RKObjectMapping *responseMapping = [RKObjectMapping mappingForClass:[MYResponse class]];
[requestMapping addAttributeMappingsFromArray:@[@"data", @"message"]];

Descriptors

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)];

Object Manager

[self.objectManager addRequestDescriptor:requestDescriptor];
[self.objectManager addResponseDescriptor:responseDescriptor];

Execute

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);
                       }];
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download