iOS 7 SDK теперь имеет лучшую альтернативу stringByAddingPercentEscapesUsingEncoding
, которая позволяет вам указать, что вы хотите экранировать все символы, кроме определенных разрешенных. Это хорошо работает, если вы создаете URL по частям:
NSString * unescapedQuery = [[NSString alloc] initWithFormat:@"?myparam=%d", numericParamValue];
NSString * escapedQuery = [unescapedQuery stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
NSString * urlString = [[NSString alloc] initWithFormat:@"http://ExampleOnly.com/path.ext%@", escapedQuery];
Хотя реже другие части URL-адреса будут переменными, в категории NSURLUtilities также есть константы:
[NSCharacterSet URLHostAllowedCharacterSet]
[NSCharacterSet URLUserAllowedCharacterSet]
[NSCharacterSet URLPasswordAllowedCharacterSet]
[NSCharacterSet URLPathAllowedCharacterSet]
[NSCharacterSet URLFragmentAllowedCharacterSet]
[NSCharacterSet URLQueryAllowedCharacterSet]
включает все символов, разрешенных в части URL-адреса запроса (часть, начинающаяся с ?
и до #
для фрагмента, если таковой имеется), включая ?
и символы &
или =
, которые используются для разделения имен и значений параметров. Для параметров запроса с буквенно-цифровыми значениями любой из этих символов может быть включен в значения переменных, используемых для построения строки запроса. В этом случае каждая часть строки запроса должна быть экранирована, что требует чуть больше работы:
NSMutableCharacterSet * URLQueryPartAllowedCharacterSet; // possibly defined in class extension ...
// ... and built in init or on first use
URLQueryPartAllowedCharacterSet = [[NSCharacterSet URLQueryAllowedCharacterSet] mutableCopy];
[URLQueryPartAllowedCharacterSet removeCharactersInString:@"&+=?"]; // %26, %3D, %3F
// then escape variables in the URL, such as values in the query and any fragment:
NSString * escapedValue = [anUnescapedValue stringByAddingPercentEncodingWithAllowedCharacters:URLQueryPartAllowedCharacterSet];
NSString * escapedFrag = [anUnescapedFrag stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLFragmentAllowedCharacterSet]];
NSString * urlString = [[NSString alloc] initWithFormat:@"http://ExampleOnly.com/path.ext?myparam=%@#%@", escapedValue, escapedFrag];
NSURL * url = [[NSURL alloc] initWithString:urlString];
unescapedValue
может быть даже целым URL, например, для обратного вызова или перенаправления:
NSString * escapedCallbackParamValue = [anAlreadyEscapedCallbackURL stringByAddingPercentEncodingWithAllowedCharacters:URLQueryPartAllowedCharacterSet];
NSURL * callbackURL = [[NSURL alloc] initWithString:[[NSString alloc] initWithFormat:@"http://ExampleOnly.com/path.ext?callback=%@", escapedCallbackParamValue]];
Примечание. Не используйте NSURL initWithScheme:(NSString *)scheme host:(NSString *)host path:(NSString *)path
для URL-адреса со строкой запроса, поскольку это приведет к добавлению дополнительных процентов к пути.