I am writing an extension to NSURL that will give it a convenience method URLFromString:withArguments: that builds an URL with some parameters included. The first argument to this method is a string like @"http://www.example.com/foo" and the second is an NSDictionary like {key1 => val1, key2 => val2}, where all of the keys and values are NSStrings. The convenience method will return an NSURL with an URL like, for this example
http://www.example.com/foo?key1=val1&key2=val2
First off, I guess I should ask whether there already exists something like this in Foundation! If not, though, my question is about properly encoding the keys and values. Much has been written on this issue (1, 2, 3). The issues with these three approaches to the problem are, respectively,
-
Inelegant. (Although it probably works. I haven’t tried it yet.)
-
Doesn’t properly escape everything.
The source recommends using
- stringByAddingPercentEscapesUsingEncodingon an NSString to escape everything. The problem is that this method doesn’t actually escape everything it should, ampersands and slashes being two obvious examples. I don’t know when this method could be useful, given these omissions, but it certainly isn’t useful for my application. -
Apparently not kosher with ARC.
I don’t know all that much about ARC yet, but the solution presented on this site uses some CoreFoundation types at which ARC balks. Xcode offers to insert
__bridgebefore a couple of type casts, and the code seems to work then, but I can’t tell whether or not I’m leaking memory or generally doing the Right Thing. And in general it seems to me like I shouldn’t have to go so low-level.
So again, my question is: is there any way to do the percent encoding required for HTTP requests that is built in to NSURL or NSString or the like? And if not, what’s the safest way?
Use (3). ARC doesn’t handle CF types directly, just as garbage-collection does not, the bridge casts are just to instruct ARC to take responsibility for the objects from CF (as
NSMakeCollectibledoes for GC). Put in the right bridge casts and you won’t be leaking any memory, see section 3.2.4 in the ARC docs