【问题标题】:What is the best practic using url string with NSString stringWithFormat将 url 字符串与 NSString stringWithFormat 一起使用的最佳做法是什么
【发布时间】:2012-08-02 21:57:14
【问题描述】:

我使用NSString stringWithFormat 方法来创建一个 URL 字符串。但现在我遇到了“快速”编辑这个字符串的问题。

例如,我在服务器上有一个脚本,它处理一些带有参数的请求。

我有一个这样的 URL 字符串:

http://www.domain.com/api/?param1=%@&param2=%@&param3=%@&param4=%@&param5=%@&

但是当我有超过 5、6 个参数时,真的很难修改这个字符串。

任何人都知道如何创建 URL 字符串的最佳方法(我的意思是当我们修改它时)。

【问题讨论】:

    标签: ios nsstring nsurl


    【解决方案1】:

    这是一个如何以安全方式添加参数的示例。长而可靠。

    NSString* const kBaseURL = @"http://maps.google.com/maps/api/geocode/xml";
    NSMutableDictionary *parameterDic = [NSMutableDictionary dictionary];
    [parameterDic setObject:@"plaza de la puerta del sol 1, madrid, spain" forKey:@"address"];
    [parameterDic setObject:@"false" forKey:@"sensor"];
    
    NSMutableArray *parameters = [NSMutableArray array];
    for (__strong NSString *name in parameterDic) {
        NSString *value = [parameterDic objectForKey:name];
        name = encodeToPercentEscapeString(name);
        value = encodeToPercentEscapeString(value);
        NSString *queryComponent = [NSString stringWithFormat:@"%@=%@", name, value];
        [parameters addObject:queryComponent];
    }
    NSString *query = [parameters componentsJoinedByString:@"&"];
    NSString *urlString = [NSString stringWithFormat:@"%@?%@", kBaseURL, query];
    NSURL *url = [NSURL URLWithString:urlString];
    NSLog(@"%@",url);
    

    上面的代码调用了这个 C 函数,因为 stringByAddingPercentEscapesUsingEncoding 不会转换参数名称或值中的一些特殊字符。正如 Jesse Rusak 所指出的,请参阅Proper URL (Percent) Encoding in iOS 进行讨论。

    // remove CFBridgingRelease and __bridge if your code is not ARC
    NSString* encodeToPercentEscapeString(NSString *string) {
        return (NSString *)
            CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(NULL,
                                                (__bridge CFStringRef) string,
                                                NULL,
                                                (CFStringRef) @"!*'();:@&=+$,/?%#[]",
                                                kCFStringEncodingUTF8));
    }
    

    打印出来

    http://maps.google.com/maps/api/geocode/xml?sensor=false&address=plaza%20de%20la%20puerta%20del%20sol%201,%20madrid,%20spain
    

    奖励曲目:如何解构和重建字符串:

    NSString *stringUrl = @"http://www.google.com:80/a/b/c;params?m=n&o=p#fragment";
    NSURL *url = [NSURL URLWithString:stringUrl];
    NSLog(@"%@",stringUrl);
    NSLog(@"         scheme: %@",[url scheme]);
    NSLog(@"           host: %@",[url host]);
    NSLog(@"           port: %@",[url port]);
    NSLog(@"           path: %@",[url path]);
    NSLog(@"   relativePath: %@",[url relativePath]);
    NSLog(@"parameterString: %@",[url parameterString]);
    NSLog(@"          query: %@",[url query]);
    NSLog(@"       fragment: %@",[url fragment]);
    
    NSMutableString *s = [NSMutableString string];
    [s appendFormat:@"%@://%@",[url scheme],[url host]];
    if ([url port]!=nil){
        [s appendFormat:@":%@",[url port]];
    }
    [s appendFormat:@"%@",[url path]];
    if ([url parameterString]!=nil){
        [s appendFormat:@";%@",[url parameterString]];
    }
    if ([url query]!=nil){
        [s appendFormat:@"?%@",[url query]];
    }
    if ([url fragment]!=nil){
        [s appendFormat:@"#%@",[url fragment]];
    }
    NSLog(@"%@",s);
    

    打印出来

    http://www.google.com:80/a/b/c;params?m=n&o=p#fragment
             scheme: http
               host: www.google.com
               port: 80
               path: /a/b/c
       relativePath: /a/b/c
    parameterString: params
              query: m=n&o=p
           fragment: fragment
    

    【讨论】:

    • 呸,不! stringByAddingPercentEscapesUsingEncoding: 不是用于此目的的正确方法。它不会在您的键或值中转义诸如“&”或“=”之类的内容。您需要使用带有适当参数或类似参数的 CFURLCreateStringByAddingPercentEscapes。
    【解决方案2】:

    我特地给你写的,很简单:

    + (NSString*) URlStringForBaseURL:(NSString*)baseURL withParams:(NSDictionary*)paramsdictonary{
    NSString* url = [baseURL stringByAppendingString:@"?"];
    NSUInteger index = 0;
    for (NSString* key in [paramsdictonary allKeys]) {
        index++;
        if (index == [paramsdictonary count]) 
            url =  [url stringByAppendingFormat:@"%@=%@",key,[paramsdictonary valueForKey:key]];
        else
            url =  [url stringByAppendingFormat:@"%@=%@&",key,[paramsdictonary valueForKey:key]];
    }
    return url;
    }
    

    你可以使用它(当然,URL参数的顺序无关紧要):

    NSMutableDictionary* params = [NSMutableDictionary dictionary];
    [params setValue:@"value1" forKey:@"param1"];
    [params setValue:@"value2" forKey:@"param2"];
    [params setValue:@"value3" forKey:@"param3"];
    
    NSString* urlStr = [HTMLTextFormat URlStringForBaseURL:@"http://www.domain.com/api/" withParams:params];
    
    NSLog(@"url_: %@",urlStr);
    

    【讨论】:

      猜你喜欢
      • 2010-10-16
      • 2012-04-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-12
      • 2018-03-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多