Eliminate use of associated objects on NSURL in favor of a smarter RKResponseDescriptor class to solve the relative URL problem. refs #966

Instead, fall back to treating all URL's as strings for matching purposes and manually performing relative URL testing. Adds `matchesURL:` and `matchesResponse:` methods to `RKResponseDescriptor`.
This commit is contained in:
Blake Watters
2012-10-04 14:11:05 -04:00
parent 73cd7a6705
commit cf5ef24fe9
10 changed files with 301 additions and 166 deletions

View File

@@ -22,7 +22,7 @@
#import "RKResponseDescriptor.h"
// Cloned from AFStringFromIndexSet -- method should be non-static for reuse
static NSString * RKStringFromIndexSet(NSIndexSet *indexSet) {
static NSString *RKStringFromIndexSet(NSIndexSet *indexSet) {
NSMutableString *string = [NSMutableString string];
NSRange range = NSMakeRange([indexSet firstIndex], 1);
@@ -52,6 +52,23 @@ static NSString * RKStringFromIndexSet(NSIndexSet *indexSet) {
return string;
}
// Assumes that URL is relative to baseURL
static NSString *RKPathAndQueryStringFromURLRelativeToURL(NSURL *URL, NSURL *baseURL)
{
if (baseURL) {
NSString *pathAndQuery = [[URL absoluteString] substringFromIndex:[[baseURL absoluteString] length]];
return ([pathAndQuery characterAtIndex:0] != '/') ? [NSString stringWithFormat:@"/%@", pathAndQuery] : pathAndQuery;
} else {
NSString *query = [URL query];
return (query && [query length]) ? [NSString stringWithFormat:@"%@?%@", [URL path], query] : [URL path];
}
}
static BOOL RKURLIsRelativeToURL(NSURL *sourceURL, NSURL *baseURL)
{
return [[sourceURL absoluteString] hasPrefix:[baseURL absoluteString]];
}
@interface RKResponseDescriptor ()
@property (nonatomic, strong, readwrite) RKMapping *mapping;
@property (nonatomic, copy, readwrite) NSString *pathPattern;
@@ -86,9 +103,32 @@ static NSString * RKStringFromIndexSet(NSIndexSet *indexSet) {
- (BOOL)matchesPath:(NSString *)path
{
if (!self.pathPattern || !path) return YES;
RKPathMatcher *pathMatcher = [RKPathMatcher pathMatcherWithPattern:self.pathPattern];
return [pathMatcher matchesPath:path tokenizeQueryStrings:NO parsedArguments:nil];
}
- (BOOL)matchesURL:(NSURL *)URL
{
NSString *pathAndQueryString = RKPathAndQueryStringFromURLRelativeToURL(URL, self.baseURL);
if (self.baseURL) {
if (! RKURLIsRelativeToURL(URL, self.baseURL)) return NO;
return [self matchesPath:pathAndQueryString];
} else {
return [self matchesPath:pathAndQueryString];
}
}
- (BOOL)matchesResponse:(NSHTTPURLResponse *)response
{
if (! [self matchesURL:response.URL]) return NO;
if (self.statusCodes) {
if (! [self.statusCodes containsIndex:response.statusCode]) {
return NO;
}
}
return YES;
}
@end