mirror of
https://github.com/zhigang1992/RestKit.git
synced 2026-04-01 22:42:51 +08:00
153 lines
5.8 KiB
Objective-C
153 lines
5.8 KiB
Objective-C
//
|
|
// RKURL.m
|
|
// RestKit
|
|
//
|
|
// Created by Jeff Arena on 10/18/10.
|
|
// Copyright 2010 RestKit
|
|
//
|
|
// 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+RestKit.h"
|
|
#import "NSString+RestKit.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];
|
|
BOOL isDirectory = [theResourcePath characterAtIndex:[theResourcePath length] - 1] == '/';
|
|
NSString *completePath = [[theBaseURL path] stringByAppendingPathComponent:resourcePathWithoutQueryString isDirectory:isDirectory];
|
|
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
|