RFC 1808 is obsoleted by RFC 3986. You care about Section 2 here. The fragment allows:
fragment = *( pchar / "/" / "?" )
pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
pct-encoded = "%" HEXDIG HEXDIG
sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
/ "*" / "+" / "," / ";" / "="
As you note, "ALPHA" here means "the basic Latin alphabet," but calling this "Latin" will often confuse people unless you're very explicit, since Latin-1 is something different. In particular, the encoding NSISOLatin1StringEncoding
is not "the basic Latin alphabet."
OK, lots of words, let's get to how to implement this. It's actually pretty simple, and Duncan's answer is close, but you shouldn't mess with the encoding. Still use UTF8 as normal:
NSString *escapedURL = [string stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
You want the percent-encoding to be based on UTF-8, and you always want Cocoa strings in UTF-8 unless you have a specific interoperability issue. As the docs say:
encoding: The encoding to use for the returned string. If you are uncertain of the correct encoding you should use NSUTF8StringEncoding.
Note that NSURL URLWithString:
requires that you already have percent-escaped the string passed to it. That sometimes surprises people (also note that "Any percent-escaped characters are interpreted using UTF-8 encoding" as noted above).