Reputation: 1647
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
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
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