Objective-C和Swift URL编码


137

我有一个NSString这样的:

http://www.

但我想将其转换为:

http%3A%2F%2Fwww.

我怎样才能做到这一点?


1
我有一个类似的加密字符串ùÕ9y^VêÏÊEØ®.ú/V÷ÅÖêú2Èh~-以下解决方案似乎都无法解决这个问题!
Mahendra Liya

Answers:


324

逃避想要的角色还需要做更多的工作。

范例程式码

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

对于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字符进行编码。

iOS7之前的版本
将Core Foundation与ARC一起使用Core Foundation:

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

在不使用ARC的情况下使用Core Foundation:

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

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

stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding 编码14个字符:

`#%^ {} [] | \“ <>加上空格字符(转义百分比)。

testString:

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

encodeString:

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

注意:请考虑这组字符是否满足您的需求,如果没有根据需要进行更改。

需要编码的RFC 3986字符(已添加%,因为它是编码前缀字符):

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

一些“未保留的字符”还被编码:

“ \ n \ r \”%-。<> \ ^ _`{|}〜“


1
还要注意,您可以使用NSString的-stringByAddingPercentEscapesUsingEncoding方法。
Mike Weller 2012年

2
嗯,是的,现在我还记得时髦的stringByAddingPercentEscapesUsingEncoding行为。它只编码'&'和'='或类似的东西。
Mike Weller 2012年

2
根据RFC1738,您还需要编码其他字符。因此,尽管这确实回答了OP的问题,但它作为通用URL编码器的用途有限。例如,它不处理非字母数字,例如德语变音符号。
Alex Nauda

3
这不起作用(适用于iOS 7部分)。这不会转换为%26。
coolcool1994

1
NSStringwith 创建所需的字符集,与with characterSetWithCharactersInString取反,invertedSet然后与with一起使用stringByAddingPercentEncodingWithAllowedCharacters。有关示例,请参见此SO答案
zaph

22

这就是所谓的URL编码这里更多。

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

3
如果答案中包含了您发布的链接中的某些内容,这将更加有用。
chown

1
CFURLCreateStringByAddingPercentEscapes()不推荐使用。使用[NSString stringByAddingPercentEncodingWithAllowedCharacters:]代替。

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;
}

如果有人告诉我谁写了这段代码,我将非常感激。基本上,他有一些解释,说明为什么此编码的字符串将完全按照其期望进行解码。

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



什么是[self UTF8String]?
Yuchao Zhou

1
@yuchaozh这是您放入NSString类别中的函数。因此,self是NSStirng,并且[self UTF8String]假定以UTF8格式返回其字符串。
凯尔西

4
 NSString * encodedString = (NSString *)CFURLCreateStringByAddingPercentEscapes(NUL,(CFStringRef)@"parameter",NULL,(CFStringRef)@"!*'();@&+$,/?%#[]~=_-.:",kCFStringEncodingUTF8 );

NSURL * url = [[NSURL alloc] initWithString:[@"address here" stringByAppendingFormat:@"?cid=%@",encodedString, nil]];

1
释放encodeString和url。该代码是关于编码参数的。要对整个地址传递字符串进行编码,而不是对“参数”进行编码。
Zahi 2012年

这对我有用...对我遇到问题的&字符进行编码。
ВикторИванов

3

这可以在Objective C ARC中使用。使用CFBridgingRelease将Core Foundation样式的对象强制转换为Objective-C对象,并将该对象的所有权转让给ARC 。请参见此处的功能CFBridgingRelease

+ (NSString *)encodeUrlString:(NSString *)string {
return CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes
                         (kCFAllocatorDefault,
                          (__bridge CFStringRef)string,
                          NULL,
                          CFSTR("!*'();:@&=+$,/?%#[]"),
                          kCFStringEncodingUTF8)
                         );}

2

Swift iOS:

仅供参考:我已经使用过:

extension String {

    func urlEncode() -> CFString {
        return CFURLCreateStringByAddingPercentEscapes(
            nil,
            self,
            nil,
            "!*'();:@&=+$,/?%#[]",
            CFStringBuiltInEncodings.UTF8.rawValue
        )
    }

}// end extension String

1
NSString *str = (NSString *)CFURLCreateStringByAddingPercentEscapes(
                             NULL,
                             (CFStringRef)yourString, 
                             NULL, 
                             CFSTR("/:"), 
                             kCFStringEncodingUTF8);

您需要自己释放或自动释放str


1

这是我用的。请注意,您必须使用该@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;
    }
}

0

Google在其Mac版Google工具箱中实现了此功能。因此,这是一个很好的地方,可以使他们达到最佳效果。另一个选择是包括工具箱并使用其实现。

此处签出实施。(这归结为人们一直在这里发布的内容)。


0

这就是我迅速进行此操作的方式。

extension String {
    func encodeURIComponent() -> String {
        return self.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLQueryAllowedCharacterSet())!
    }

    func decodeURIComponent() -> String {
        return self.componentsSeparatedByString("+").joinWithSeparator(" ").stringByRemovingPercentEncoding!
    }
}

-1

//使用NSString实例方法,如下所示:

+ (NSString *)encodeURIComponent:(NSString *)string
{
NSString *s = [string stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
return s;
}

+ (NSString *)decodeURIComponent:(NSString *)string
{
NSString *s = [string stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
return s;
}

请记住,您只应该对参数值进行编码或解码,而不要对您请求的所有网址进行编码或解码。


2
stringByReplacingPercentEscapeusingencoding:仅逸出&并= :-(
塞巴斯蒂安Stormacq

1
正确,因此+之类的东西在需要时不进行编码。因此,请不要使用上述答案
John Ballinger

-8
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 );
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.