github twitter linkedin instagram
Objective-C long URL parameter encoding
Dec 24, 2013
One minute read

I was looking for a simple way to build URL’s with long parameter lists. There were two problems that I ran into:

  1. The CFURLCreateStringByAddingPercentEscapes method apparently isn’t completely fool proof.

  2. [NSString stringWithFormat] gets messy with a lot of parameters.

So I created a class to trivialize the handling of this circumstance.

#import <Foundation/Foundation.h>

@interface UrlParameterBuilder : NSObject {
	NSMutableDictionary* parameters;
}
-(UrlParameterBuilder*)init;
-(UrlParameterBuilder*)initWithParameterDictionary:(NSDictionary*)parameterDictionary;
-(void)addParamWithTitle:(NSString*)title andValue:(NSString*)value;
-(NSString*)getUrlString;
@end




#import "URLParameterBuilder.h"
@implementation UrlParameterBuilder
-(UrlParameterBuilder*)init {
	self = [super init];
	parameters = [NSMutableDictionary dictionary];
	return self;
}
-(UrlParameterBuilder*)initWithParameterDictionary:(NSDictionary*)parameterDictionary {
	self = [super init];
	parameters = [NSMutableDictionary dictionaryWithDictionary:parameterDictionary];
	return self;
}
-(void)addParamWithTitle:(NSString*)title andValue:(NSString*)value {
	[parameters setObject:value forKey:title];
}
-(NSString*)getUrlString {
	NSMutableString* result = [NSMutableString string];

	BOOL firstIterationComplete = NO;
	for (NSString* key in parameters) {
		[result appendFormat:@"%c%@=%@",
			firstIterationComplete ? '&' : '?',
			key,
			[self urlEncodeString:[parameters objectForKey:key]]
		];
		firstIterationComplete = YES;
	}
	return [NSString stringWithString:result];
}
-(NSString*)urlEncodeString:(NSString*)unencodedString {
	NSString* encodedString = (__bridge NSString*)CFURLCreateStringByAddingPercentEscapes(
			NULL,
			(__bridge CFStringRef)unencodedString,
			NULL,
			CFSTR("!*'();:@&=+$,/?%#[]\" "),
			kCFStringEncodingUTF8);
	return encodedString;
}
@end

The usage is quite simple:

UrlParameterBuilder* builder = [[UrlParameterBuilder alloc] initWithParameterDictionary:@{
	@"First param":@")+]*&[}{)+]*htnaoeunsht Jibberish",
	@"user":@"Username",
	@"query":@"Some query.",
}];

if (we_want_sorting) {
	[builder addParamWithTitle:@"sort" andValue:@"desc"];
}

NSog(@"Nicely encoded params: %@", [builder getUrlString]);

Back to posts