The character set URLQueryAllowedCharacterSet
contains all the characters allowed in the query part of the URL ( ..?key1=value1&key2=value2
), and is not limited to the characters allowed in the keys and values โโof such a query. For instance. URLQueryAllowedCharacterSet
contains &
and +
, since they are of course allowed in the request ( &
separates key / value pairs and +
means space), but they are not allowed in the key or the value of such a request.
Consider this code:
NSString * key = "my&name"; NSString * value = "test+test"; NSString * safeKey= [key stringByAddingPercentEncodingWithAllowedCharacters: [NSCharacterSet URLQueryAllowedCharacterSet] ]; NSString * safeValue= [value stringByAddingPercentEncodingWithAllowedCharacters: [NSCharacterSet URLQueryAllowedCharacterSet] ]; NSString * query = [NSString stringWithFormat:@"?%@=%@", safeKey, safeValue];
query
will be ?my&name=test+test
, which is completely wrong. It defines a key with the name my
, which does not matter, and a key with the name name
, whose value is test test
(+ means a space!).
The correct query would be ?my%26name=test%2Btest
.
As long as you use only ASCII strings or as long as the server can deal with UTF-8 characters in the URL (most web servers do this today), the number of characters you absolutely must encode is actually quite small and very constant. Just try this code:
NSCharacterSet * queryKVSet = [NSCharacterSet characterSetWithCharactersInString:":/?&=; +!@ #$()',*% " ].invertedSet; NSString * value = ...; NSString * valueSafe = [value stringByAddingPercentEncodingWithAllowedCharacters:queryKVSet ];
source share