Заметка: -stringByAddingPercentEscapesUsingEncoding не будет производить правильную кодировку, в этом случае он не будет кодировать ничего, возвращающее ту же строку.
Также обратите внимание, что вы можете использовать -stringByAddingPercentEscapesUsingEncodingметод NSString .
Майк Веллер,
2
Ах, да, теперь я вспоминаю это странное stringByAddingPercentEscapesUsingEncodingповедение. Он кодирует только '&' и '=' или что-нибудь в этом роде.
Майк Веллер,
2
Согласно RFC1738 вам также потребуется кодировать дополнительные символы. Таким образом, хотя это действительно ответ на вопрос OP, он имеет ограниченную полезность в качестве универсального кодировщика URL. Например, он не обрабатывает не буквенно-цифровые символы, такие как немецкий умляут.
Alex Nauda 05
3
Это не работает (для части iOS 7). Это не преобразует & в% 26.
coolcool1994
1
Создайте нужный набор символов из NSStringwith characterSetWithCharactersInString, возьмите обратное invertedSetи используйте его с stringByAddingPercentEncodingWithAllowedCharacters. Для примера см. Этот SO-ответ .
Если кто-то скажет мне, кто написал этот код, я буду очень признателен. По сути, у него есть объяснение, почему эта закодированная строка будет декодироваться именно так, как ей хочется.
Я немного изменил его решение. Мне нравится, когда пространство обозначается% 20, а не +. Вот и все.
@yuchaozh - это функция, которую вы помещаете в категорию NSString. Итак, self - это NSStirng, а [self UTF8String] возвращает, предположительно, свою строку в формате UTF8.
освободить encodedString и url. этот код касается параметра кодирования. Для кодирования всего адреса передайте строку вместо «параметра».
Захи
Это сработало для меня ... закодировал даже символ &, с которым у меня были проблемы.
Виктор Иванов
3
Это может работать в Objective C ARC. Используйте CFBridgingRelease, чтобы преобразовать объект в стиле Core Foundation как объект Objective-C и передать право собственности на объект ARC. См . Функцию CFBridgingRelease здесь.
Вот что я использую. Обратите внимание, что вы должны использовать@autoreleasepool функцию, иначе программа может вывести из строя или заблокировать IDE. Мне пришлось перезапустить свою IDE три раза, пока я не понял, как исправить. Похоже, что этот код совместим с ARC.
Этот вопрос задавали много раз, и было дано много ответов, но, к сожалению, все выбранные (и несколько других предложенных) неверны.
Вот тестовая строка, которую я использовал: This is my 123+ test & test2. Got it?!
Google реализует это в своей панели инструментов Google для Mac . Так что это хорошее место, чтобы увидеть, как они это делают. Другой вариант - включить Toolbox и использовать их реализацию.
Ознакомьтесь с реализацией здесь . (Это сводится к тому, что люди здесь публикуют).
ùÕ9y^VêÏÊEØ®.ú/V÷ÅÖêú2Èh~
- ни одно из приведенных ниже решений не решает эту проблему!Ответы:
Чтобы избежать нужных вам персонажей, потребуется немного больше работы.
Пример кода
NSString *unescaped = @"http://www"; NSString *escapedString = [unescaped stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLHostAllowedCharacterSet]]; NSLog(@"escapedString: %@", escapedString);
Вывод NSLog:
Ниже приведены полезные наборы символов кодировки URL:
URLFragmentAllowedCharacterSet "#%<>[\]^`{|} URLHostAllowedCharacterSet "#%/<>?@\^`{|} URLPasswordAllowedCharacterSet "#%/:<>?@[\]^`{|} URLPathAllowedCharacterSet "#%;<>?[\]^`{|} URLQueryAllowedCharacterSet "#%<>[\]^`{|} URLUserAllowedCharacterSet "#%/:<>?@[\]^`
Создание набора символов, сочетающего все вышеперечисленное:
NSCharacterSet *URLCombinedCharacterSet = [[NSCharacterSet characterSetWithCharactersInString:@" \"#%/:<>?@[\\]^`{|}"] invertedSet];
Создание Base64
В случае набора символов Base64:
NSCharacterSet *URLBase64CharacterSet = [[NSCharacterSet characterSetWithCharactersInString:@"/+=\n"] invertedSet];
var escapedString = originalString.addingPercentEncoding(withAllowedCharacters:.urlHostAllowed)
var escapedString = originalString.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLHostAllowedCharacterSet())
Примечание:
stringByAddingPercentEncodingWithAllowedCharacters
также будут кодироваться символы UTF-8, требующие кодировки.NSString *escapedString = (NSString *)CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes( NULL, (__bridge CFStringRef) unescaped, NULL, CFSTR("!*'();:@&=+$,/?%#[]\" "), kCFStringEncodingUTF8));
Использование Core Foundation без ARC:
NSString *escapedString = (NSString *)CFURLCreateStringByAddingPercentEscapes( NULL, (CFStringRef)unescaped, NULL, CFSTR("!*'();:@&=+$,/?%#[]\" "), kCFStringEncodingUTF8);
Заметка:
-stringByAddingPercentEscapesUsingEncoding
не будет производить правильную кодировку, в этом случае он не будет кодировать ничего, возвращающее ту же строку.stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding
кодирует 14 символов:testString:
" `~!@#$%^&*()_+-={}[]|\\:;\"'<,>.?/AZaz"
encodedString:
"%20%60~!@%23$%25%5E&*()_+-=%7B%7D%5B%5D%7C%5C:;%22'%3C,%3E.?/AZaz"
Примечание: подумайте, соответствует ли этот набор символов вашим потребностям, если не измените их по мере необходимости.
RFC 3986 символов, требующих кодировки (добавлен%, поскольку это символ префикса кодировки):
Некоторые «незарезервированные символы» дополнительно кодируются:
источник
-stringByAddingPercentEscapesUsingEncoding
метод NSString .stringByAddingPercentEscapesUsingEncoding
поведение. Он кодирует только '&' и '=' или что-нибудь в этом роде.NSString
withcharacterSetWithCharactersInString
, возьмите обратноеinvertedSet
и используйте его сstringByAddingPercentEncodingWithAllowedCharacters
. Для примера см. Этот SO-ответ .Это называется кодировкой URL . Подробнее здесь .
-(NSString *)urlEncodeUsingEncoding:(NSStringEncoding)encoding { return (NSString *)CFURLCreateStringByAddingPercentEscapes(NULL, (CFStringRef)self, NULL, (CFStringRef)@"!*'\"();:@&=+$,/?%#[]% ", CFStringConvertNSStringEncodingToEncoding(encoding)); }
источник
CFURLCreateStringByAddingPercentEscapes()
не рекомендуется.[NSString stringByAddingPercentEncodingWithAllowedCharacters:]
Вместо этого используйте .Это не мое решение. Кто-то еще писал в stackoverflow, но я забыл, как это сделать.
Как-то это решение работает "хорошо". Он обрабатывает диакритические знаки, китайские иероглифы и многое другое.
- (NSString *) URLEncodedString { NSMutableString * output = [NSMutableString string]; const char * source = [self UTF8String]; int sourceLen = strlen(source); for (int i = 0; i < sourceLen; ++i) { const unsigned char thisChar = (const unsigned char)source[i]; if (false && thisChar == ' '){ [output appendString:@"+"]; } else if (thisChar == '.' || thisChar == '-' || thisChar == '_' || thisChar == '~' || (thisChar >= 'a' && thisChar <= 'z') || (thisChar >= 'A' && thisChar <= 'Z') || (thisChar >= '0' && thisChar <= '9')) { [output appendFormat:@"%c", thisChar]; } else { [output appendFormat:@"%%%02X", thisChar]; } } return output; }
Если кто-то скажет мне, кто написал этот код, я буду очень признателен. По сути, у него есть объяснение, почему эта закодированная строка будет декодироваться именно так, как ей хочется.
Я немного изменил его решение. Мне нравится, когда пространство обозначается% 20, а не +. Вот и все.
источник
NSString * encodedString = (NSString *)CFURLCreateStringByAddingPercentEscapes(NUL,(CFStringRef)@"parameter",NULL,(CFStringRef)@"!*'();@&+$,/?%#[]~=_-.:",kCFStringEncodingUTF8 ); NSURL * url = [[NSURL alloc] initWithString:[@"address here" stringByAppendingFormat:@"?cid=%@",encodedString, nil]];
источник
Это может работать в Objective C ARC. Используйте CFBridgingRelease, чтобы преобразовать объект в стиле Core Foundation как объект Objective-C и передать право собственности на объект ARC. См . Функцию CFBridgingRelease здесь.
+ (NSString *)encodeUrlString:(NSString *)string { return CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes (kCFAllocatorDefault, (__bridge CFStringRef)string, NULL, CFSTR("!*'();:@&=+$,/?%#[]"), kCFStringEncodingUTF8) );}
источник
Swift iOS:
Просто для информации: я использовал это:
extension String { func urlEncode() -> CFString { return CFURLCreateStringByAddingPercentEscapes( nil, self, nil, "!*'();:@&=+$,/?%#[]", CFStringBuiltInEncodings.UTF8.rawValue ) } }// end extension String
источник
NSString *str = (NSString *)CFURLCreateStringByAddingPercentEscapes( NULL, (CFStringRef)yourString, NULL, CFSTR("/:"), kCFStringEncodingUTF8);
Вам нужно будет освободить или автоматически выпустить
str
себя.источник
Вот что я использую. Обратите внимание, что вы должны использовать
@autoreleasepool
функцию, иначе программа может вывести из строя или заблокировать IDE. Мне пришлось перезапустить свою IDE три раза, пока я не понял, как исправить. Похоже, что этот код совместим с ARC.Этот вопрос задавали много раз, и было дано много ответов, но, к сожалению, все выбранные (и несколько других предложенных) неверны.
Вот тестовая строка, которую я использовал:
This is my 123+ test & test2. Got it?!
Это мои методы класса Objective C ++:
static NSString * urlDecode(NSString *stringToDecode) { NSString *result = [stringToDecode stringByReplacingOccurrencesOfString:@"+" withString:@" "]; result = [result stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; return result; } static NSString * urlEncode(NSString *stringToEncode) { @autoreleasepool { NSString *result = (NSString *)CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes( NULL, (CFStringRef)stringToEncode, NULL, (CFStringRef)@"!*'\"();:@&=+$,/?%#[]% ", kCFStringEncodingUTF8 )); result = [result stringByReplacingOccurrencesOfString:@"%20" withString:@"+"]; return result; } }
источник
Google реализует это в своей панели инструментов Google для Mac . Так что это хорошее место, чтобы увидеть, как они это делают. Другой вариант - включить Toolbox и использовать их реализацию.
Ознакомьтесь с реализацией здесь . (Это сводится к тому, что люди здесь публикуют).
источник
Вот как я делаю это быстро.
extension String { func encodeURIComponent() -> String { return self.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLQueryAllowedCharacterSet())! } func decodeURIComponent() -> String { return self.componentsSeparatedByString("+").joinWithSeparator(" ").stringByRemovingPercentEncoding! } }
источник
// использовать метод экземпляра NSString следующим образом:
+ (NSString *)encodeURIComponent:(NSString *)string { NSString *s = [string stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; return s; } + (NSString *)decodeURIComponent:(NSString *)string { NSString *s = [string stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; return s; }
помните, вы должны кодировать или декодировать только значение вашего параметра, а не весь запрашиваемый URL.
источник
int strLength = 0; NSString *urlStr = @"http://www"; NSLog(@" urlStr : %@", urlStr ); NSMutableString *mutableUrlStr = [urlStr mutableCopy]; NSLog(@" mutableUrlStr : %@", mutableUrlStr ); strLength = [mutableUrlStr length]; [mutableUrlStr replaceOccurrencesOfString:@":" withString:@"%3A" options:NSCaseInsensitiveSearch range:NSMakeRange(0, strLength)]; NSLog(@" mutableUrlStr : %@", mutableUrlStr ); strLength = [mutableUrlStr length]; [mutableUrlStr replaceOccurrencesOfString:@"/" withString:@"%2F" options:NSCaseInsensitiveSearch range:NSMakeRange(0, strLength)]; NSLog(@" mutableUrlStr : %@", mutableUrlStr );
источник