Objective - C и Swift URL кодирование
у меня есть NSString
такой:
http://www.
но я хочу преобразовать его в:
http%3A%2F%2Fwww.
как я могу это сделать?
12 ответов:
чтобы избежать символов, которые вы хотите немного больше работы.
пример кода
iOS7 и выше:
NSString *unescaped = @"http://www"; NSString *escapedString = [unescaped stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLHostAllowedCharacterSet]]; NSLog(@"escapedString: %@", escapedString);
NSLog выход:
escapedString: http%3A%2F%2Fwww
следующие полезные наборы символов кодировки URL:
URLFragmentAllowedCharacterSet "#%<>[\]^`{|} URLHostAllowedCharacterSet "#%/<>?@\^`{|} URLPasswordAllowedCharacterSet "#%/:<>?@[\]^`{|} URLPathAllowedCharacterSet "#%;<>?[\]^`{|} URLQueryAllowedCharacterSet "#%<>[\]^`{|} URLUserAllowedCharacterSet "#%/:<>?@[\]^`
создание набора символов, объединяющего все вышеперечисленное:
NSCharacterSet *URLCombinedCharacterSet = [[NSCharacterSet characterSetWithCharactersInString:@" \"#%/:<>?@[\]^`{|}"] invertedSet];
создание Base64
In случай набора символов Base64:
NSCharacterSet *URLBase64CharacterSet = [[NSCharacterSet characterSetWithCharactersInString:@"/+=\n"] invertedSet];
Для Swift 3.0:
var escapedString = originalString.addingPercentEncoding(withAllowedCharacters:.urlHostAllowed)
Для Swift 2.x:
var escapedString = originalString.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLHostAllowedCharacterSet())
Примечание:
stringByAddingPercentEncodingWithAllowedCharacters
также будет кодировать UTF - 8 символов, нуждающихся в кодировке.Pre iOS7 использовать Core Foundation
Использование основного фундамента с дугой:NSString *escapedString = (NSString *)CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes( NULL, (__bridge CFStringRef) unescaped, NULL, CFSTR("!*'();:@&=+$,/?%#[]\" "), kCFStringEncodingUTF8));
использование основного фундамента без дуги:
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 символов требуется кодировка (% добавлено, так как это символ префикса кодировки):
"!#$&'()*+,/:;=?@[]%"
некоторые" незащищенные символы " дополнительно кодируются:
" \n\r \"% -.\^_`{|}~"
Это называется кодировка URL. Еще здесь.
-(NSString *)urlEncodeUsingEncoding:(NSStringEncoding)encoding { return (NSString *)CFURLCreateStringByAddingPercentEscapes(NULL, (CFStringRef)self, NULL, (CFStringRef)@"!*'\"();:@&=+$,/?%#[]% ", CFStringConvertNSStringEncodingToEncoding(encoding)); }
Это не мое решение. Кто-то еще написал в 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-style в качестве объекта 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);
вам нужно будет выпустить или autorelease
str
себя.
компания Google реализует это в своих Google Toolbox для Mac. Так что это хорошее место, чтобы пик, как они это делают. Другой вариант-включить инструментарий и использовать их реализацию.
проверка выполнения здесь. (Что сводится именно к тому, что люди публикуют здесь).
вот как я делаю это в swift.
extension String { func encodeURIComponent() -> String { return self.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLQueryAllowedCharacterSet())! } func decodeURIComponent() -> String { return self.componentsSeparatedByString("+").joinWithSeparator(" ").stringByRemovingPercentEncoding! } }
вот что я использую. Обратите внимание, что вы должны использовать
@autoreleasepool
функция или программа может аварийно завершить работу или заблокировать IDE. Мне пришлось перезапустить IDE три раза, пока я не понял исправление. Похоже, что этот код соответствует ARC.этот вопрос задавался много раз, и многие ответы были даны, но, к сожалению, все выбранные (и несколько других предложенных) ошибочны.
вот тестовая строка, которую я использовал:
This is my 123+ test & test2. Got it?!
Это мой объективный класс 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; } }
/ / используйте метод экземпляра 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 );