R2r
R2r

Reputation: 1647

Restkit resources mapping depending on parameters

I'm strating to use RetKit, but documentation could be better.

How can I register mappings for resources relying on request parameter? Unfortunatelly I don't have well written service to consume, so that all my resources are in somexamplepath.com/api/ but asking about one is done by parameter like: somexamplepath.com/api/?res=people or somexamplepath.com/api/?res=machines

What is the best way to do mappings for such situation?

Upvotes: 1

Views: 849

Answers (2)

abbood
abbood

Reputation: 23548

you are talking about the same resource with different query strings. Just add the query string parameter when you send the request.. ie

NSDictionary *params = @{@"res":@"people"};
[[RKObjectManager sharedManager] getObjectsAtPath:@"api/" 
                                       parameters:params
                                          success:^(RKObjectRequestOperation *operation,
                                                    RKMappingResult *mappingResult) {
     // blah blah

here is a more comprehensive example from my own code.. i totally understand the whole "documentation could be better".. notice i have two entity mappings (for two different entities).. event and attendee:

// Configure the object manager
_objectManager = [RKObjectManager managerWithBaseURL:[NSURL URLWithString:@"http://mydomain.com/api/v1"]];
_objectManager.managedObjectStore = _managedObjectStore;

[RKObjectManager setSharedManager:_objectManager];

_objectManager.requestSerializationMIMEType=RKMIMETypeJSON;

RKEntityMapping *eventEntityMapping = [RKEntityMapping mappingForEntityForName:@"Event" inManagedObjectStore:_managedObjectStore];
[eventEntityMapping addAttributeMappingsFromDictionary:@{
                                                    @"id":             @"id",
                                                    @"resource_uri":   @"resource_uri",
                                                    @"title":          @"title",
                                                    @"city":           @"city",
                                                    @"from_date":      @"from_date",
                                                    @"user":           @"user_id"}];

eventEntityMapping.identificationAttributes = @[ @"id" ];



RKResponseDescriptor *eventResponseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:eventEntityMapping pathPattern:@"event/" keyPath:@"objects" statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)];

[_objectManager addResponseDescriptor:eventResponseDescriptor];

RKEntityMapping *attendeeEntityMapping = [RKEntityMapping mappingForEntityForName:@"Attendee" inManagedObjectStore:_managedObjectStore];
[attendeeEntityMapping addAttributeMappingsFromDictionary:@{
                                               @"id":                     @"id",
                                               @"order.first_name":       @"first_name",
                                               @"order.last_name":        @"last_name",
                                               @"unique":        @"order_ticket_unique_code",
                                               @"ticket.event":           @"event_id",
                                               @"ticket.description":     @"ticket_description",
                                               @"ticket.perk":            @"ticket_perk",
                                               @"ticket.price":           @"ticket_price"}];

attendeeEntityMapping.identificationAttributes = @[ @"id" ];



RKResponseDescriptor *attendeeResponseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:attendeeEntityMapping pathPattern:@"orderticket/search/" keyPath:@"objects" statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)];
_objectManager.requestSerializationMIMEType=RKMIMETypeJSON;

[_objectManager addResponseDescriptor:attendeeResponseDescriptor];

later on i simply fetch an attendee resource (in the api it's called orderticket.. whatever)

- (void)downloadAttendees
{

    NSDictionary *params = @{@"q":_eventId};
    [[RKObjectManager sharedManager] getObjectsAtPath:@"orderticket/search/" parameters:params success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
        [self.tableView reloadData];
        [self.refreshControl endRefreshing];
    } failure:^(RKObjectRequestOperation *operation, NSError *error) {
        [self.refreshControl endRefreshing];
        UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"An Error Has Occurred" message:[error localizedDescription] delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
        [alertView show];
    }];
}

and i also fetch an event resource (event resource don't take a query string):

- (void)downloadEvents
{
    [[RKObjectManager sharedManager] getObjectsAtPath:@"event/" parameters:nil success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
        [self.tableView reloadData];
        [self.refreshControl endRefreshing];
    } failure:^(RKObjectRequestOperation *operation, NSError *error) {
        [self.refreshControl endRefreshing];
        UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"An Error Has Occurred" message:[error localizedDescription] delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
        [alertView show];
    }];
}

Upvotes: 1

Wain
Wain

Reputation: 119031

This situation is not well covered because RestKit matches against URL paths, not query parameters.

You could use multiple instances of RKObjectManager where each instance is to be used for a particular subset of your API content.

I haven't tried this, but it may be possible to setup a 2 stage process where the URL path is used to match initially and that takes you to an RKDynamicMapping. In the dynamic mapping you can then use RKObjectMappingMatcher which gives access to predicate based matching using matcherWithPredicate:objectMapping:. If the @metadata.URL key is available to the predicate you can match all of the query parameters there.

Upvotes: 2

Related Questions