Objective-C和Swift URL编码

Usi*_*Usi 135 objective-c urlencode nsstring ios swift

NSString喜欢这样的:

http://www.
Run Code Online (Sandbox Code Playgroud)

但我想将其转换为:

http%3A%2F%2Fwww.
Run Code Online (Sandbox Code Playgroud)

我怎样才能做到这一点?

zap*_*aph 321

逃避你想要的角色是一个更多的工作.

示例代码

iOS7及以上版本:

NSString *unescaped = @"http://www";
NSString *escapedString = [unescaped stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLHostAllowedCharacterSet]];
NSLog(@"escapedString: %@", escapedString);
Run Code Online (Sandbox Code Playgroud)

NSLog输出:

escapedString:http%3A%2F%2Fwww

以下是有用的URL编码字符集:

URLFragmentAllowedCharacterSet  "#%<>[\]^`{|}
URLHostAllowedCharacterSet      "#%/<>?@\^`{|}
URLPasswordAllowedCharacterSet  "#%/:<>?@[\]^`{|}
URLPathAllowedCharacterSet      "#%;<>?[\]^`{|}
URLQueryAllowedCharacterSet     "#%<>[\]^`{|}
URLUserAllowedCharacterSet      "#%/:<>?@[\]^`
Run Code Online (Sandbox Code Playgroud)

创建一个结合了以上所有内容的字符:

NSCharacterSet *URLCombinedCharacterSet = [[NSCharacterSet characterSetWithCharactersInString:@" \"#%/:<>?@[\\]^`{|}"] invertedSet];
Run Code Online (Sandbox Code Playgroud)

创建Base64

在Base64字符集的情况下:

NSCharacterSet *URLBase64CharacterSet = [[NSCharacterSet characterSetWithCharactersInString:@"/+=\n"] invertedSet];
Run Code Online (Sandbox Code Playgroud)

对于Swift 3.0:

var escapedString = originalString.addingPercentEncoding(withAllowedCharacters:.urlHostAllowed)
Run Code Online (Sandbox Code Playgroud)

对于Swift 2.x:

var escapedString = originalString.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLHostAllowedCharacterSet())
Run Code Online (Sandbox Code Playgroud)

注意:stringByAddingPercentEncodingWithAllowedCharacters还将编码需要编码的UTF-8字符.

Pre iOS7使用Core Foundation
使用Core Foundation with ARC:

NSString *escapedString = (NSString *)CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(
    NULL,
   (__bridge CFStringRef) unescaped,
    NULL,
    CFSTR("!*'();:@&=+$,/?%#[]\" "),
    kCFStringEncodingUTF8));
Run Code Online (Sandbox Code Playgroud)

使用没有ARC的Core Foundation:

NSString *escapedString = (NSString *)CFURLCreateStringByAddingPercentEscapes(
    NULL,
   (CFStringRef)unescaped,
    NULL,
    CFSTR("!*'();:@&=+$,/?%#[]\" "),
    kCFStringEncodingUTF8);
Run Code Online (Sandbox Code Playgroud)

注意:-stringByAddingPercentEscapesUsingEncoding不会产生正确的编码,在这种情况下,它不会编码返回相同字符串的任何内容.

stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding 编码14个字符:

`#%^ {} [] | \"<>加上空格字符作为百分比转义.

的TestString:

" `~!@#$%^&*()_+-={}[]|\\:;\"'<,>.?/AZaz"  
Run Code Online (Sandbox Code Playgroud)

encodedString:

"%20%60~!@%23$%25%5E&*()_+-=%7B%7D%5B%5D%7C%5C:;%22'%3C,%3E.?/AZaz"  
Run Code Online (Sandbox Code Playgroud)

注意:考虑这组字符是否满足您的需求,如果不根据需要更改它们.

需要编码的RFC 3986字符(由于它是编码前缀字符,因此添加了%):

"#$&'()*+,/:;!?= @ []%"

一些"未保留的字符"另外编码:

"\n\r \"% - .<>\^ _` {|}〜"

  • 这不起作用(适用于iOS 7部分).这不会转换成%26. (3认同)
  • 是的,现在我记得那个时髦的`stringByAddingPercentEscapesUsingEncoding`行为.它只编码'&'和'='或类似的荒谬. (2认同)
  • 根据[RFC1738](http://www.ietf.org/rfc/rfc1738.txt),您还需要编码其他字符.因此,虽然这确实回答了OP的问题,但它作为通用URL编码器的用处有限.例如,它不处理非字母数字,如德国变音符号. (2认同)

lar*_*cus 22

它被称为URL编码.更多这里.

-(NSString *)urlEncodeUsingEncoding:(NSStringEncoding)encoding {
    return (NSString *)CFURLCreateStringByAddingPercentEscapes(NULL,
           (CFStringRef)self,
           NULL,
           (CFStringRef)@"!*'\"();:@&=+$,/?%#[]% ",
           CFStringConvertNSStringEncodingToEncoding(encoding));
}
Run Code Online (Sandbox Code Playgroud)

  • 如果您发布的链接中的某些内容包含在答案中,这将更有用. (3认同)

Ano*_*ite 7

这不是我的解决方案.其他人在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;
}
Run Code Online (Sandbox Code Playgroud)

如果有人告诉我谁编写了这段代码,我会非常感激.基本上他有一些解释为什么这个编码的字符串将完全按照它的意愿解码.

我稍微修改了他的解决方案.我喜欢用%20而不是+来表示空格.就这样.