andreas nilsson
andreas nilsson

Reputation: 1

RestKit 0.20 map request and respone with different mappings

Im connecting my iOS app to a restful webservice (WCF) where the request doesnt look the same as the response and im really having a hard time finding this in the restkit documentation.

Basically i have two classes that are related. ClassA has a collection of ClassB. When I send an instance of ClassB to the webservice the attribute that identifies the pk of the other class (ClassA) is called "ClassA", just as excpected.

But, when the server successfully has added the object it sends it back and not the same attribute is called "ClassB1" (the microsoft way).

I´m thinking that i want to use two different mappings because just using "inverseMapping" isn´t really doing it for me. Anyone has any ideas?

Upvotes: 0

Views: 2187

Answers (3)

andreas nilsson
andreas nilsson

Reputation: 1

The problem was solved by using RKObjectMapping in mElling´s answer as docksteaderluke suggested but only after I updated RestKit to version 0.20-pre6.

Upvotes: 0

docksteaderluke
docksteaderluke

Reputation: 2245

To use RKEntityMapping stick with mElling's answer but replace:

RKObjectMapping *returnedObjectMapping = [RKObjectMapping mappingForClass:[ReturnedModel class]];
[returnedObjectMapping addAttributeMappingsFromDictionary:@{
 @"returnedParam1" : @"returnedParam1",
 @"returnedParam2": @"returnedParam2",
 @"returnedParam3": @"returnedParam3"}];

with:

RKEntityMapping *returnedObjectMapping = [RKEntityMapping mappingForEntityForName:@"ReturnedModel" inManagedObjectStore:objectManager.managedObjectStore];
[returnedObjectMapping addAttributeMappingsFromArray:@[@"returnedParam1", @"returnedParam2", @"returnedParam3"]];

Note: You'll also have to move the lines where you set the "objectManager" variable to somewhere before your returnedObjectMapping.

Upvotes: 2

mElling
mElling

Reputation: 197

You're correct in thinking that two mappings is the answer. Assuming you are using the newest versions of RestKit, something like the following will work.

Also keep in mind that in order to really leverage what RestKit has to offer, the JSON must be Key Value Coding compliant. For instance, in this example the JSON is wrapped in a "Response" key.

I just pulled this from a project I'm working on and changed all of the names. This should get you going on the right path.

RKObjectMapping *postObjectMapping = [RKObjectMapping requestMapping];
[postObjectMapping addAttributeMappingsFromDictionary:@{
 @"param1" : @"param1",
 @"param2" : @"param2"}];

RKRequestDescriptor *requestDescriptor = [RKRequestDescriptor requestDescriptorWithMapping:postObjectMapping objectClass:[PostObjectModel class] rootKeyPath:nil];

RKObjectMapping *returnedObjectMapping = [RKObjectMapping mappingForClass:[ReturnedModel class]];
[returnedObjectMapping addAttributeMappingsFromDictionary:@{
 @"returnedParam1" : @"returnedParam1",
 @"returnedParam2": @"returnedParam2",
 @"returnedParam3": @"returnedParam3"}];

RKResponseDescriptor *responseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:returnedObjectMapping pathPattern:nil keyPath:@"Response" statusCodes:[NSIndexSet indexSetWithIndex:200]];

RKObjectMapping *errorMapping = [RKObjectMapping mappingForClass:[RKErrorMessage class]];
[errorMapping addPropertyMapping:[RKAttributeMapping attributeMappingFromKeyPath:@"error" toKeyPath:@"errorMessage"]];

NSIndexSet *statusCodes = RKStatusCodeIndexSetForClass(RKStatusCodeClassClientError);
RKResponseDescriptor *errorDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:errorMapping pathPattern:nil keyPath:@"errors" statusCodes:statusCodes];


PostModel *objectToBePosted = [PostModel new];
[login setParam1:something];
[login setParam2:something];

RKObjectManager *objectManager = [RKObjectManager managerWithBaseURL:[NSURL URLWithString:@"http://BASEURLHERE"]];
[objectManager addRequestDescriptor:requestDescriptor];
[objectManager addResponseDescriptor:responseDescriptor];
[objectManager addResponseDescriptor:errorDescriptor];

NSMutableURLRequest *request = [objectManager requestWithObject:objectToBePosted method:RKRequestMethodPOST path:@"/REST/OF/PATH/GOES/HERE" parameters:nil];

RKObjectRequestOperation *operation = [objectManager objectRequestOperationWithRequest:request
    success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
        NSLog(@"Success block: %@", mappingResult);
    } failure: ^(RKObjectRequestOperation *operation, NSError *error) {
        NSLog(@"Failed with error: %@", [error localizedDescription]);
    }];

[objectManager enqueueObjectRequestOperation:operation];

}

Upvotes: 3

Related Questions