I’m trying to use the object loader to fetch objects from an API with that needs to pass in a type as a query parameter (e.g. http://example.com/api/households/:householdId/checklist_items?kind=todo) but no matter which way I try registering the resource path it doesn’t seem to want to locate my mapping.
I’m setting up a mapping like this:
RKObjectMapping* mapping = [RKObjectMapping mappingForClass:[RMChecklistItem class]];
[mapping mapKeyPath:@"id" toAttribute:@"checklistItemId"];
[mapping mapKeyPath:@"kind" toAttribute:@"kind"];
[mapping mapKeyPath:@"title" toAttribute:@"title"];
[mapping mapKeyPath:@"completed" toAttribute:@"completed"];
[mapping mapKeyPath:@"abilities" toAttribute:@"abilities"];
[mapping mapKeyPath:@"comments" toRelationship:@"comments"
withMapping:[provider objectMappingForClass:[RMComment class]]];
And registering it with the object mapping provider using the base path and a version with the query string:
[provider addObjectMapping:mapping];
[provider setObjectMapping:mapping forResourcePathPattern:@"/api/households/:householdId/checklist_items"];
[provider setObjectMapping:mapping forResourcePathPattern:@"/api/households/:householdId/checklist_items?kind=:kind"];
But when I try to use it:
NSDictionary *params [NSDictionary dictionaryWithObject:@"todo" forKey:@"kind"];
NSString *path = [NSString stringWithFormat:@"/api/households/%i/checklist_items", householdId.intValue];
[[RKObjectManager sharedManager] loadObjectsAtResourcePath:[path stringByAppendingQueryParameters:params] usingBlock:^(RKObjectLoader *loader) {
loader.onDidLoadObjects = ^(NSArray *objects) {
NSLog(@"%@", objects);
};
loader.onDidFailWithError = ^(NSError *error) {
NSLog(@"%@", error);
};
loader.onDidFailLoadWithError = ^(NSError *error) {
NSLog(@"%@", error);
};
}];
It goes badly:
2012-07-20 12:13:18.533 roommates[22399:13d03] D restkit.object_mapping:RKObjectMapper.m:336 Performing object mapping sourceObject: (
{
abilities = {
destroy = 1;
};
comments = (
);
completed = 0;
id = 44;
kind = todo;
title = "and do the dishes";
},
{
abilities = {
destroy = 1;
};
comments = (
{
body = "your!";
"created_at" = "2012-07-18T22:20:08-05:00";
"creator_id" = 16;
id = 70;
}
);
completed = 0;
id = 43;
kind = todo;
title = "pick you shit up";
},
{
abilities = {
destroy = 1;
};
comments = (
{
body = "did it";
"created_at" = "2012-07-18T22:19:56-05:00";
"creator_id" = 16;
id = 69;
}
);
completed = 0;
id = 40;
kind = todo;
title = "Pay Rent";
}
)
and targetObject: (null)
2012-07-20 12:13:18.539 roommates[22399:13d03] T restkit.object_mapping:RKObjectMapper.m:293 Examining keyPath 'users' for mappable content...
2012-07-20 12:13:18.539 roommates[22399:13d03] D restkit.object_mapping:RKObjectMapper.m:120 Found a collection containing only NSNull values, considering the collection unmappable...
2012-07-20 12:27:47.702 roommates[22399:13d03] D restkit.object_mapping:RKObjectMapper.m:303 Found unmappable value at keyPath: users
2012-07-20 12:27:47.705 roommates[22399:13d03] D restkit.object_mapping:RKObjectMapper.m:367 The following operations are in the queue: (
)
2012-07-20 12:27:51.065 roommates[22399:13d03] W restkit.object_mapping:RKObjectMapper.m:87 Adding mapping error: Could not find an object mapping for keyPath: ''
2012-07-20 12:27:51.066 roommates[22399:13d03] E restkit.network:RKObjectLoader.m:234 Encountered errors during mapping: Could not find an object mapping for keyPath: ''
So watching the flow in the debugger I came across RKObjectMappingProvider’s
mappingForPatternMatchingString:context:which calls RKPathMatcher’smatchesPath:string tokenizeQueryStrings:NO parsedArguments:nilso I guess this is by design.I’ve really only got two possible values for the query parameter ‘todo’ and ‘shopping’ so it wasn’t unreasonable to register both both.
Update: I submitted a pull request that changes this to parse tokens in query strings: https://github.com/RestKit/RestKit/pull/871