Skip to content
Fetching contributors…
Cannot retrieve contributors at this time
169 lines (139 sloc) 5.85 KB
//
// RKURL.m
// RestKit
//
// Created by Jeff Arena on 10/18/10.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import "RKURL.h"
#import "RKClient.h"
#import "NSURL+RKAdditions.h"
#import "NSString+RKAdditions.h"
#import "NSDictionary+RKAdditions.h"
#import "RKLog.h"
@interface RKURL ()
@property (nonatomic, copy, readwrite) NSURL *baseURL;
@property (nonatomic, copy, readwrite) NSString *resourcePath;
@end
@implementation RKURL
@synthesize baseURL;
@synthesize resourcePath;
+ (id)URLWithBaseURL:(NSURL *)baseURL
{
return [self URLWithBaseURL:baseURL resourcePath:nil queryParameters:nil];
}
+ (id)URLWithBaseURL:(NSURL *)baseURL resourcePath:(NSString *)resourcePath
{
return [self URLWithBaseURL:baseURL resourcePath:resourcePath queryParameters:nil];
}
+ (id)URLWithBaseURL:(NSURL *)baseURL resourcePath:(NSString *)resourcePath queryParameters:(NSDictionary *)queryParameters
{
return [[[self alloc] initWithBaseURL:baseURL resourcePath:resourcePath queryParameters:queryParameters] autorelease];
}
+ (id)URLWithBaseURLString:(NSString *)baseURLString
{
return [self URLWithBaseURLString:baseURLString resourcePath:nil queryParameters:nil];
}
+ (id)URLWithBaseURLString:(NSString *)baseURLString resourcePath:(NSString *)resourcePath
{
return [self URLWithBaseURLString:baseURLString resourcePath:resourcePath queryParameters:nil];
}
+ (id)URLWithBaseURLString:(NSString *)baseURLString resourcePath:(NSString *)resourcePath queryParameters:(NSDictionary *)queryParameters
{
return [self URLWithBaseURL:[NSURL URLWithString:baseURLString] resourcePath:resourcePath queryParameters:queryParameters];
}
// Designated initializer. Note this diverges from NSURL due to a bug in Cocoa. We can't
// call initWithString:relativeToURL: from a subclass.
- (id)initWithBaseURL:(NSURL *)theBaseURL resourcePath:(NSString *)theResourcePath queryParameters:(NSDictionary *)theQueryParameters
{
// Merge any existing query parameters with the incoming dictionary
NSDictionary *resourcePathQueryParameters = [theResourcePath queryParameters];
NSMutableDictionary *mergedQueryParameters = [NSMutableDictionary dictionaryWithDictionary:[theBaseURL queryParameters]];
[mergedQueryParameters addEntriesFromDictionary:resourcePathQueryParameters];
[mergedQueryParameters addEntriesFromDictionary:theQueryParameters];
// Build the new URL path
NSRange queryCharacterRange = [theResourcePath rangeOfCharacterFromSet:[NSCharacterSet characterSetWithCharactersInString:@"?"]];
NSString *resourcePathWithoutQueryString = (queryCharacterRange.location == NSNotFound) ? theResourcePath : [theResourcePath substringToIndex:queryCharacterRange.location];
NSString *baseURLPath = [[theBaseURL path] isEqualToString:@"/"] ? @"" : [[theBaseURL path] stringByStandardizingPath];
NSString *completePath = resourcePathWithoutQueryString ? [baseURLPath stringByAppendingString:resourcePathWithoutQueryString] : baseURLPath;
NSString *completePathWithQuery = [completePath stringByAppendingQueryParameters:mergedQueryParameters];
// NOTE: You can't safely use initWithString:relativeToURL: in a NSURL subclass, see http://www.openradar.me/9729706
// So we unfortunately convert into an NSURL before going back into an NSString -> RKURL
NSURL *completeURL = [NSURL URLWithString:completePathWithQuery relativeToURL:theBaseURL];
if (!completeURL) {
RKLogError(@"Failed to build RKURL by appending resourcePath and query parameters '%@' to baseURL '%@'", theResourcePath, theBaseURL);
[self release];
return nil;
}
self = [self initWithString:[completeURL absoluteString]];
if (self) {
self.baseURL = theBaseURL;
self.resourcePath = theResourcePath;
}
return self;
}
- (void)dealloc
{
[baseURL release];
baseURL = nil;
[resourcePath release];
resourcePath = nil;
[super dealloc];
}
- (NSDictionary *)queryParameters
{
if (self.query) {
return [NSDictionary dictionaryWithURLEncodedString:self.query];
}
return nil;
}
- (RKURL *)URLByAppendingResourcePath:(NSString *)theResourcePath
{
return [RKURL URLWithBaseURL:self resourcePath:theResourcePath];
}
- (RKURL *)URLByAppendingResourcePath:(NSString *)theResourcePath queryParameters:(NSDictionary *)theQueryParameters
{
return [RKURL URLWithBaseURL:self resourcePath:theResourcePath queryParameters:theQueryParameters];
}
- (RKURL *)URLByAppendingQueryParameters:(NSDictionary *)theQueryParameters
{
return [RKURL URLWithBaseURL:self resourcePath:nil queryParameters:theQueryParameters];
}
- (RKURL *)URLByReplacingResourcePath:(NSString *)newResourcePath
{
return [RKURL URLWithBaseURL:self.baseURL resourcePath:newResourcePath];
}
- (RKURL *)URLByInterpolatingResourcePathWithObject:(id)object
{
return [self URLByReplacingResourcePath:[self.resourcePath interpolateWithObject:object]];
}
#pragma mark - NSURL Overloads
/*
Overload implementations from NSURL. We consider a naked string to be initialized
with a baseURL == self. Otherwise appending/replacing resourcePath will not work.
*/
+ (id)URLWithString:(NSString *)URLString
{
return [self URLWithBaseURLString:URLString];
}
- (id)initWithString:(NSString *)URLString
{
self = [super initWithString:URLString];
if (self) {
self.baseURL = self;
}
return self;
}
@end
Something went wrong with that request. Please try again.