转义查询网址字符串的百分比

时间:2014-01-08 16:44:02

标签: ios sdk nsstring

我收到的NSString为http://maps.apple.com/maps?saddr=41.447910,-74.357881&daddr=719 Old Route 9 North, Wappingers Falls, NY 12590

但是我需要将上面的字符串转换为给出的用于在地图中显示位置的字符串

http://maps.apple.com/maps?saddr=41.447910,-74.357881&daddr=719+Old%20Route+9+North%2CWappingers+Falls%2CNY+12590

请告诉我。

6 个答案:

答案 0 :(得分:9)

您可以使用以下内容执行此操作...

NSString *theOrigString = @"http://maps.apple.com/maps?saddr=41.447910,-74.357881&daddr=719 Old Route 9 North, Wappingers Falls, NY 12590";

NSString *formattedString = [theOrigString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];

NSLog(@"%@", formattedString);

<强>输出

http://maps.apple.com/maps?saddr=41.447910,-74.357881&daddr=719%20Old%20Route%2‌​09%20North,%20Wappingers%20Falls,%20NY%2012590

这将用%20替换空格,依此类推。

然后,您可以将其用作网址字符串。

答案 1 :(得分:2)

一个老问题,但这就是你需要的:

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

-(NSString*) decodeFromPercentEscapeString:(NSString *)string {
return (NSString *)CFBridgingRelease(CFURLCreateStringByReplacingPercentEscapesUsingEncoding(NULL,
                                                        (CFStringRef) string,
                                                        CFSTR(""),
                                                        kCFStringEncodingUTF8)); }

答案 2 :(得分:0)

查看NSString的{​​{1}}

stringByAddingPercentEscapesUsingEncoding:

答案 3 :(得分:0)

编码百分比背后的原因仅来自RFC 3986。简而言之,您应该转义URI 查询参数的百分比值以转义保留字符(“!*'();:@&amp; = + $,/ ?%#[]“)。这样做可以正确地解码编码的URI - 为了简单起见,假设两侧的编码相同。

正如Duncan和Fogmeister所指出的那样,Apple的stringByAddingPercentEscapesUsingEncoding非常友好,但总的来说,错误 - 或者至少说,不符合RFC 3986 - 因为没有' t%转义字符如“/:&amp;%?”。

更通用,更强大的解决方案就像

NSString * HKObjectToString(id object) {
    return [NSString stringWithFormat:@"%@", object];
}   

NSString * HKPercentEscapedString(id object, CFStringEncoding encoding) {
    NSString *string = HKObjectToString(object);
    return ((NSString *)CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(NULL, (__bridge CFStringRef) string, NULL,
                                                                              CFSTR("!*'();:@&=+$,/?%#[]"),
                                                                              encoding)));
}

...
@implementation NSDictionary (URLAdditions)
...
- (NSString *)percentEscapedQueryStringWithEncoding:(CFStringEncoding)encoding
{
    NSMutableArray *queryParts = [[NSMutableArray alloc] init];
    for (NSString *key in [self allKeys]) {
        NSString *part = [NSString stringWithFormat:@"%@=%@", HKPercentEscapedString(key, encoding), HKPercentEscapedString(HKObjectToString(self[key]), encoding)];
        [queryParts addObject:part];
    }
    return [queryParts componentsJoinedByString:@"&"];
}
...
@end 

...
@implementation NSString (StringHelper)
...
+ (NSString *)URIEncodedWithStringURI:(NSString *)baseURI queryParameters:(NSDictionary *)queryParams URIEncoding:(CFStringEncoding)encoding
{
    return [NSString stringWithFormat:@"%@?%@", baseURI, [queryParams percentEscapedQueryStringWithEncoding:encoding]];
}
...
@end

有关详细信息,请尝试在github上查看此公开repo

答案 4 :(得分:0)

此问题存在问题,因为输入数据已损坏。在代码的某个早期点,此URL被解码为单个字符串。您永远不应该这样做,因为它可能导致URL的不同部分之间的区别丢失并且永远无法恢复的情况。例如,假设我有这个URL:

http://www.example.com/folder/this%2Fthat.html

解码后,变为

http://www.example.com/folder/this/that.html

并且没有办法将其转回原始版本,因为无法知道哪些斜线是真实的,哪些应该编码为%2F。这种区别完全失去了。

出于这个原因,当您使用URL时,务必尽可能始终以原始形式保留它们,并且当您必须解码URL时,这样做是分段的 - 也就是说,首先拆分所有URL路径组件,查询字符串等,然后拉开查询字符串中的字段(如果适用),最后单独解码每个部分。

之后,您需要使用CFURLCreateStringByReplacingPercentEscapesUsingEncoding对每个部分进行重新编码,因为上面的NSString方法不会对斜杠,符号和其他特殊URL字符进行百分比编码。

但在您的情况下,最好的办法是找到解码URL的代码,并将其删除,以便您拥有原始未损坏的URL。如果且,如果不可能,则stringByAddingPercentEscapesUsingEncoding:方法可以对编码内容做出“最佳猜测”,只要您了解对于任意URL,该解决方案就不一定有效。

答案 5 :(得分:-1)

编辑:

Sulthan有一点意见。如果字符串部分(如本例中的地址)可能包含保留的URL字符(&#34; /&#34;,&#34;:&#34;,&),则不能对整个URL进行编码百分比编码。 #34;&amp;&#34;,&#34;%&#34;,&#34;?&#34;等。)

stringByAddingPercentEscapesUsingEncoding方法对空格进行编码,但不对斜线,冒号等进行编码。因此,如果地址字符串包含其中任何一个,则URL的接收者无法说明URL的语法部分是什么以及什么数据。

我有一类NSString也可以逃避这些字符:

标题

#import <Foundation/Foundation.h>

@interface NSString (URLEncoding) 
- (NSString *)stringByAddingPercentEscapes;
- (NSString *)stringByReplacingPercentEscapes; 
@end 
NSString *mapURLStringTemplate = 
  @"http://maps.apple.com/maps?saddr=%f,%f&daddr=%@";

身体:

#import "StringCategory.h"

CFStringRef charsToEscape = CFSTR(":/&=");

@implementation NSString (URLEncoding) 

- (NSString *)stringByAddingPercentEscapes 
{ 
    return (NSString *)CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(NULL, 
                                                                (CFStringRef)self, NULL, charsToEscape, 
                                                                CFStringConvertNSStringEncodingToEncoding(NSUTF8StringEncoding))); 
} 

- (NSString *)stringByReplacingPercentEscapes 
{ 
    return (NSString *)CFBridgingRelease(CFURLCreateStringByReplacingPercentEscapes(kCFAllocatorDefault,(CFStringRef)self, CFSTR(""))); 
} 

@end 

使用它:

NSString *escapedAddressString = 
  [addressString stringByAddingPercentEscapes];

NSString *mapURLString = 
  [NSString stringWithFormat: mapURLStringTemplate, 
  latitude, 
  longitude, 
  escapedAddressString];