Implemented RKMakePathWithObject. Cleaned up some TODO's

This commit is contained in:
Blake Watters
2011-01-20 11:24:47 -05:00
parent 88943469d8
commit bf1cadc72e
6 changed files with 57 additions and 47 deletions

View File

@@ -34,6 +34,18 @@ NSURL* RKMakeURL(NSString* resourcePath);
*/
NSString* RKMakeURLPath(NSString* resourcePath);
/**
* Convenience method for generating a path against the properties of an object. Takes
* a string with property names encoded in parentheses and interpolates the values of
* the properties specified and returns the generated path.
*
* For example, given an 'article' object with an 'articleID' property of 12345
* RKMakePathWithObject(@"articles/(articleID)", article) would generate @"articles/12345"
*
* This functionality is the basis for resource path generation in the Router.
*/
NSString* RKMakePathWithObject(NSString* path, id object);
/////////////////////////////////////////////////////////////////////////
/**

View File

@@ -27,6 +27,42 @@ NSString* RKMakeURLPath(NSString* resourcePath) {
return [[RKClient sharedClient] URLPathForResourcePath:resourcePath];
}
NSString* RKMakePathWithObject(NSString* path, id object) {
NSMutableDictionary* substitutions = [NSMutableDictionary dictionary];
NSScanner* scanner = [NSScanner scannerWithString:path];
BOOL startsWithParentheses = [[path substringToIndex:1] isEqualToString:@"("];
while ([scanner isAtEnd] == NO) {
NSString* keyPath = nil;
if (startsWithParentheses || [scanner scanUpToString:@"(" intoString:nil]) {
// Advance beyond the opening parentheses
if (NO == [scanner isAtEnd]) {
[scanner setScanLocation:[scanner scanLocation] + 1];
}
if ([scanner scanUpToString:@")" intoString:&keyPath]) {
NSString* searchString = [NSString stringWithFormat:@"(%@)", keyPath];
NSString* propertyStringValue = [NSString stringWithFormat:@"%@", [object valueForKeyPath:keyPath]];
[substitutions setObject:propertyStringValue forKey:searchString];
}
}
}
if (0 == [substitutions count]) {
return path;
}
NSMutableString* interpolatedPath = [[path mutableCopy] autorelease];
for (NSString* find in substitutions) {
NSString* replace = [substitutions valueForKey:find];
[interpolatedPath replaceOccurrencesOfString:find
withString:replace
options:NSLiteralSearch
range:NSMakeRange(0, [interpolatedPath length])];
}
return [NSString stringWithString:interpolatedPath];
}
///////////////////////////////////////////////////////////////////////////////////////////////////
@implementation RKClient

View File

@@ -74,40 +74,6 @@
#pragma mark RKRouter
- (NSString*)resourcePath:(NSString*)resourcePath withPropertiesInterpolatedForObject:(NSObject<RKObjectMappable>*)object {
NSMutableDictionary* substitutions = [NSMutableDictionary dictionary];
NSScanner* scanner = [NSScanner scannerWithString:resourcePath];
BOOL startsWithParentheses = [[resourcePath substringToIndex:1] isEqualToString:@"("];
while ([scanner isAtEnd] == NO) {
NSString* keyPath = nil;
if (startsWithParentheses || [scanner scanUpToString:@"(" intoString:nil]) {
// Advance beyond the opening parentheses
if (NO == [scanner isAtEnd]) {
[scanner setScanLocation:[scanner scanLocation] + 1];
}
if ([scanner scanUpToString:@")" intoString:&keyPath]) {
NSString* searchString = [NSString stringWithFormat:@"(%@)", keyPath];
NSString* propertyStringValue = [NSString stringWithFormat:@"%@", [object valueForKeyPath:keyPath]];
[substitutions setObject:propertyStringValue forKey:searchString];
}
}
}
if (0 == [substitutions count]) {
return resourcePath;
}
NSMutableString* interpolatedResourcePath = [[resourcePath mutableCopy] autorelease];
for (NSString* find in substitutions) {
NSString* replace = [substitutions valueForKey:find];
[interpolatedResourcePath replaceOccurrencesOfString:find withString:replace
options:NSLiteralSearch range:NSMakeRange(0, [interpolatedResourcePath length])];
}
return [NSString stringWithString:interpolatedResourcePath];
}
- (NSString*)resourcePathForObject:(NSObject<RKObjectMappable>*)object method:(RKRequestMethod)method {
NSString* methodName = [self HTTPVerbForMethod:method];
NSString* className = NSStringFromClass([object class]);
@@ -115,11 +81,11 @@
NSString* resourcePath = nil;
if (resourcePath = [classRoutes objectForKey:methodName]) {
return [self resourcePath:resourcePath withPropertiesInterpolatedForObject:object];
return RKMakePathWithObject(resourcePath, object);
}
if (resourcePath = [classRoutes objectForKey:@"ANY"]) {
return [self resourcePath:resourcePath withPropertiesInterpolatedForObject:object];
return RKMakePathWithObject(resourcePath, object);
}
[NSException raise:nil format:@"Unable to find a routable path for object of type '%@' for HTTP Method '%@'", className, methodName];