У меня есть NSString:
http://www.
но я хочу преобразовать его в:
http%3A%2F%2Fwww.
Как я могу это сделать?
У меня есть NSString:
http://www.
но я хочу преобразовать его в:
http%3A%2F%2Fwww.
Как я могу это сделать?
Чтобы избежать символов, которые вы хотите, это немного больше.
Пример кода
iOS7 и выше:
NSString *unescaped = @"http://www";
NSString *escapedString = [unescaped stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLHostAllowedCharacterSet]];
NSLog(@"escapedString: %@", escapedString);
Выход NSLog:
escapedString: http% 3A% 2F% 2Fwww
Ниже перечислены полезные URL-коды кодировки:
URLFragmentAllowedCharacterSet  "#%<>[\]^`{|}
URLHostAllowedCharacterSet      "#%/<>[email protected]\^`{|}
URLPasswordAllowedCharacterSet  "#%/:<>[email protected][\]^`{|}
URLPathAllowedCharacterSet      "#%;<>?[\]^`{|}
URLQueryAllowedCharacterSet     "#%<>[\]^`{|}
URLUserAllowedCharacterSet      "#%/:<>[email protected][\]^`
Создание набора символов, объединяющего все вышесказанное:
NSCharacterSet *URLCombinedCharacterSet = [[NSCharacterSet characterSetWithCharactersInString:@" \"#%/:<>[email protected][\\]^`{|}"] invertedSet];
Создание Base64
В случае набора символов 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
Использование Core Foundation с ARC:
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:
" `[email protected]#$%^&*()_+-={}[]|\\:;\"'<,>.?/AZaz"  
encodedString:
"%20%[email protected]%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]];
NSString *str = (NSString *)CFURLCreateStringByAddingPercentEscapes(
                             NULL,
                             (CFStringRef)yourString, 
                             NULL, 
                             CFSTR("/:"), 
                             kCFStringEncodingUTF8);
Вам нужно будет освободить или autorelease str самостоятельно.
Swift iOS:
Только для информации: я использовал это:
extension String {
    func urlEncode() -> CFString {
        return CFURLCreateStringByAddingPercentEscapes(
            nil,
            self,
            nil,
            "!*'();:@&=+$,/?%#[]",
            CFStringBuiltInEncodings.UTF8.rawValue
        )
    }
}// end extension String
Это может работать в Objective C ARC.Use CFBridgingRelease, чтобы отличить объект типа Core Foundation как объект Objective-C и передать право собственности на объект в ARC. Смотрите Функция CFBridgingRelease здесь.
+ (NSString *)encodeUrlString:(NSString *)string {
return CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes
                         (kCFAllocatorDefault,
                          (__bridge CFStringRef)string,
                          NULL,
                          CFSTR("!*'();:@&=+$,/?%#[]"),
                          kCFStringEncodingUTF8)
                         );}
Google реализует это в Google Toolbox для Mac. Так что хорошее место, чтобы пик, как они это делают. Другой вариант - включить Toolbox и использовать их реализацию.
Оформить заказ здесь. (Что сводится к тому, что люди публикуют здесь).
Вот как я делаю это быстро.
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?!
Это мои методы класса Objective С++:
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 );