-
-
Save mramsden/972328 to your computer and use it in GitHub Desktop.
NSDictionary *queryParameters = [NSDictionary dictionaryWithValuesAndKeys:1, @"page", nil, @"enabled", 25, @"size", nil]; | |
[queryParameters queryString]; // This will return "?page=1&enabled&size=25" |
#import <Foundation/Foundation.h> | |
@interface NSDictionary (QueryStringBuilder) | |
- (NSString *)queryString; | |
@end |
#import "NSDictionary+QueryStringBuilder.h" | |
static NSString * escapeString(NSString *unencodedString) | |
{ | |
NSString *s = (NSString *)CFURLCreateStringByAddingPercentEscapes(NULL, | |
(CFStringRef)unencodedString, | |
NULL, | |
(CFStringRef)@"!*'\"();:@&=+$,/?%#[]% ", | |
kCFStringEncodingUTF8); | |
return [s autorelease]; | |
} | |
@implementation NSDictionary (QueryStringBuilder) | |
- (NSString *)queryString | |
{ | |
NSMutableString *queryString = nil; | |
NSArray *keys = [self allKeys]; | |
if ([keys count] > 0) { | |
for (id key in keys) { | |
id value = [self objectForKey:key]; | |
if (nil == queryString) { | |
queryString = [[[NSMutableString alloc] init] autorelease]; | |
[queryString appendFormat:@"?"]; | |
} else { | |
[queryString appendFormat:@"&"]; | |
} | |
if (nil != key && nil != value) { | |
[queryString appendFormat:@"%@=%@", escapeString(key), escapeString(value)]; | |
} else if (nil != key) { | |
[queryString appendFormat:@"%@", escapeString(key)]; | |
} | |
} | |
} | |
return queryString; | |
} | |
@end |
id value = [self objectForKey:key]
if value was NSArray, what would happen?
@bigpandras that's a good question, with a bit of a lengthy answer.
To answer your question. At the moment I would assume that there would be a crash since there is nothing special handling an array vs. a string. The call to escapeString
expects an NSString *
to be passed, so if you passed an NSArray *
I would expect a crash or some other undefined behaviour as without running this code I'm not sure what happens if you cast an NSArray
to a CFStringRef
.
All of that being said I would strongly encourage you to have a look at NSURLComponents
and specifically the queryItems
property. Since I used this snippet Apple has now added some supported API although it is based on the key and value both being strings.
Realistically if you wanted to use this code or Apple's you would need to establish how your API handles an array of values for a query parameter. I can think of a number of different scenarios:
- Joining an array with a series of comma separated values
- Repeating your key name e.g.
key=value1&key=value2
This entirely depends on how the API works you are trying to use expects these parameters. I hope that helps!
Thanks for the spots :)