How to properly percent-encode a URL string?

I've got a text field in which the user can enter a URL. This is given to my app as an NSString, which of course needs to be turned into an NSURL. Traditionally what I've done has been to call -[NSString stringByReplacingPercentEscapesUsingEncoding:] on the string to turn any percent escapes the user may have typed into the raw characters, and then -[NSString stringByAddingPercentEscapesUsingEncoding:] to convert those, and any raw Unicode characters the user may have entered, back into percent escapes, resulting in a nice escaped URL string that NSURL won't choke on in its -initWithString: method.


However, in El Capitan, both -[NSString stringByReplacingPercentEscapesUsingEncoding:] and -[NSString stringByAddingPercentEscapesUsingEncoding:] are deprecated, with the suggestion to use -[NSString stringByAddingPercentEscapesWithAllowedCharacters:] instead. However, the documentation for that method says the following:


"This method is intended to percent-encode an URL component or subcomponent string, NOT the entire URL string."


So how are you supposed to encode an entire URL string? I can pretty trivially create a URL string that will make -[NSURL initWithString:] return nil if it's not escaped first.

Accepted Answer

You can try creating an instance of NSURLComponents with the string to see if it's more robust.


If not, Apple's advice, in the 10.11 release notes, is:


If you need to percent-encode an entire URL string, you can use this code to encode a NSString intended to be a URL (in urlStringToEncode):

NSString *percentEncodedURLString =
[[NSURL URLWithDataRepresentation:[urlStringToEncode dataUsingEncoding:NSUTF8StringEncoding] relativeToURL:nil] relativeString];

You can try creating an instance of NSURLComponents with the string to see if it's more robust.


Forgot to mention that; I tried that, it chokes on the same things that -[NSURL initWithURL:] chokes on.


If not, Apple's advice, in the 10.11 release notes, is:


If you need to percent-encode an entire URL string, you can use this code to encode a NSString intended to be a URL (in urlStringToEncode):

NSString *percentEncodedURLString =
[[NSURL URLWithDataRepresentation:[urlStringToEncode dataUsingEncoding:NSUTF8StringEncoding] relativeToURL:nil] relativeString];


That worked. Strange that I missed that in the release notes. Thanks for the help.

How to properly percent-encode a URL string?
 
 
Q