NSURL为参数字符串中的键提取单个值

时间:2010-02-09 00:02:39

标签: nsurl

我有一个NSURL:

serverCall X = A&安培; Y = B和Z = C

获得y值的最快捷,最有效的方法是什么?

由于

15 个答案:

答案 0 :(得分:79)

<强>更新

自2010年撰写本文以来,Apple似乎已经发布了一套用于此目的的工具。请参阅下面的答案。

老派解决方案:

嗯,我知道你说过“最快的方式”,但在我开始用NSScanner进行测试后,我无法停止。虽然它不是最短的方式,但如果你计划大量使用这个功能,它肯定很方便。我创建了一个URLParser类,使用NSScanner获取这些变量。用法很简单:

URLParser *parser = [[[URLParser alloc] initWithURLString:@"http://blahblahblah.com/serverCall?x=a&y=b&z=c&flash=yes"] autorelease];
NSString *y = [parser valueForVariable:@"y"];
NSLog(@"%@", y); //b
NSString *a = [parser valueForVariable:@"a"];
NSLog(@"%@", a); //(null)
NSString *flash = [parser valueForVariable:@"flash"];
NSLog(@"%@", flash); //yes

执行此操作的类如下(*帖子底部的*源文件):

<强> URLParser.h

@interface URLParser : NSObject {
    NSArray *variables;
}

@property (nonatomic, retain) NSArray *variables;

- (id)initWithURLString:(NSString *)url;
- (NSString *)valueForVariable:(NSString *)varName;

@end

<强> URLParser.m

@implementation URLParser
@synthesize variables;

- (id) initWithURLString:(NSString *)url{
    self = [super init];
    if (self != nil) {
        NSString *string = url;
        NSScanner *scanner = [NSScanner scannerWithString:string];
        [scanner setCharactersToBeSkipped:[NSCharacterSet characterSetWithCharactersInString:@"&?"]];
        NSString *tempString;
        NSMutableArray *vars = [NSMutableArray new];
        [scanner scanUpToString:@"?" intoString:nil];       //ignore the beginning of the string and skip to the vars
        while ([scanner scanUpToString:@"&" intoString:&tempString]) {
            [vars addObject:[tempString copy]];
        }
        self.variables = vars;
        [vars release];
    }
    return self;
}

- (NSString *)valueForVariable:(NSString *)varName {
    for (NSString *var in self.variables) {
        if ([var length] > [varName length]+1 && [[var substringWithRange:NSMakeRange(0, [varName length]+1)] isEqualToString:[varName stringByAppendingString:@"="]]) {
            NSString *varValue = [var substringFromIndex:[varName length]+1];
            return varValue;
        }
    }
    return nil;
}

- (void) dealloc{
    self.variables = nil;
    [super dealloc];
}

@end

*如果你不喜欢复制和粘贴,你可以下载源文件 - 我发了一篇关于这个here的快速博客文章。

答案 1 :(得分:63)

这里有很多自定义网址解析器,请记住 NSURLComponents 是你的朋友!

以下是我为“page”

提取url编码参数的示例

<强>夫特

let myURL = "www.something.com?page=2"

var pageNumber : Int?
if let queryItems = NSURLComponents(string: myURL)?.queryItems {
    for item in queryItems {
        if item.name == "page" {
           if let itemValue = item.value {
               pageNumber = Int(itemValue)
           }
        }
    }
}
print("Found page number: \(pageNumber)")

<强>目标C

NSString *myURL = @"www.something.com?page=2";
NSURLComponents *components = [NSURLComponents componentsWithString:myURL];
NSNumber *page = nil;
for(NSURLQueryItem *item in components.queryItems)
{
    if([item.name isEqualToString:@"page"])
        page = [NSNumber numberWithInteger:item.value.integerValue];
}

“为什么重新发明轮子!” - 某人智能

答案 2 :(得分:19)

我很确定你必须自己解析它。但是,它并不太糟糕:

NSString * q = [myURL query];
NSArray * pairs = [q componentsSeparatedByString:@"&"];
NSMutableDictionary * kvPairs = [NSMutableDictionary dictionary];
for (NSString * pair in pairs) {
  NSArray * bits = [pair componentsSeparatedByString:@"="];
  NSString * key = [[bits objectAtIndex:0] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
  NSString * value = [[bits objectAtIndex:1] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
  [kvPairs setObject:value forKey:key];
}

NSLog(@"y = %@", [kvPairs objectForKey:@"y"]);

答案 3 :(得分:11)

在Swift中,您可以使用NSURLComponents将NSURL的查询字符串解析为[AnyObject]。

然后,您可以从中创建字典(或直接访问项目)以获取键/值对。作为一个例子,我正在使用它来解析NSURL变量url:

let urlComponents = NSURLComponents(URL: url, resolvingAgainstBaseURL: false)
let items = urlComponents?.queryItems as [NSURLQueryItem]
var dict = NSMutableDictionary()
for item in items{
    dict.setValue(item.value, forKey: item.name)
}
println(dict["x"])

答案 4 :(得分:10)

我一直在使用此类别:https://github.com/carlj/NSURL-Parameters

它小巧易用:

#import "NSURL+Parameters.h"
...
NSURL *url = [NSURL URLWithString:@"http://foo.bar.com?paramA=valueA&paramB=valueB"];
NSString *paramA = url[@"paramA"];
NSString *paramB = url[@"paramB"];

答案 5 :(得分:4)

您可以使用Google Toolbox for Mac。 它为NSString添加了一个函数,用于将查询字符串转换为字典。

http://code.google.com/p/google-toolbox-for-mac/

它就像一个魅力

        NSDictionary * d = [NSDictionary gtm_dictionaryWithHttpArgumentsString:[[request URL] query]];

答案 6 :(得分:4)

这是一个Swift 2.0扩展,提供对参数的简单访问:

$arr_res = $_POST['people']

样本用法:

extension NSURL {
    var params: [String: String] {
        get {
            let urlComponents = NSURLComponents(URL: self, resolvingAgainstBaseURL: false)
            var items = [String: String]()
            for item in urlComponents?.queryItems ?? [] {
                items[item.name] = item.value ?? ""
            }
            return items
        }
    }
} 

答案 7 :(得分:3)

我写了一个简单的类别来扩展NSString / NSURL,它允许你单独提取URL查询参数或者作为键/值对的字典提取:

https://github.com/nicklockwood/RequestUtils

答案 8 :(得分:2)

我使用基于@Dimitris解决方案的类别方法

#import "NSURL+DictionaryValue.h"

@implementation NSURL (DictionaryValue)
-(NSDictionary *)dictionaryValue
{
NSString *string =  [[self.absoluteString stringByReplacingOccurrencesOfString:@"+" withString:@" "]
                     stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSScanner *scanner = [NSScanner scannerWithString:string];
[scanner setCharactersToBeSkipped:[NSCharacterSet characterSetWithCharactersInString:@"&?"]];

NSString *temp;
NSMutableDictionary *dict = [[[NSMutableDictionary alloc] init] autorelease];
[scanner scanUpToString:@"?" intoString:nil];       //ignore the beginning of the string and skip to the vars
while ([scanner scanUpToString:@"&" intoString:&temp]) 
{
    NSArray *parts = [temp componentsSeparatedByString:@"="];
    if([parts count] == 2)
    {
        [dict setObject:[parts objectAtIndex:1] forKey:[parts objectAtIndex:0]];
    }
}

return dict;
}
@end

答案 9 :(得分:0)

我建议查看getResourceValue:forKey:error:。我相信forKey参数将为y

答案 10 :(得分:0)

你可以这么做:

- (NSMutableDictionary *) getUrlParameters:(NSURL *) url
{
    NSMutableDictionary *params = [[NSMutableDictionary alloc] init];
    NSString *tmpKey = [url query];
    for (NSString *param in [[url query] componentsSeparatedByString:@"="])
    {
        if ([tmpKey rangeOfString:param].location == NSNotFound)
        {
            [params setValue:param forKey:tmpKey];
            tmpKey = nil;
        }
        tmpKey = param;
    }
    [tmpKey release];

    return params;
}

它像它一样返回Dictionary:Key = value

答案 11 :(得分:0)

我编辑了Dimitris&#39;稍微代码以获得更好的内存管理和效率。此外,它适用于ARC。

<强> URLParser.h

@interface URLParser : NSObject

- (void)setURLString:(NSString *)url;
- (NSString *)valueForVariable:(NSString *)varName;

@end

<强> URLParser.m

#import "URLParser.h"

@implementation URLParser {
    NSMutableDictionary *_variablesDict;
}

- (void)setURLString:(NSString *)url {
    [_variablesDict removeAllObjects];

    NSString *string = url;
    NSScanner *scanner = [NSScanner scannerWithString:string];
    [scanner setCharactersToBeSkipped:[NSCharacterSet characterSetWithCharactersInString:@"&?"]];
    NSString *tempString;

    [scanner scanUpToString:@"?" intoString:nil];       //ignore the beginning of the string and skip to the vars
    while ([scanner scanUpToString:@"&" intoString:&tempString]) {
        NSString *dataString = [tempString copy];
        NSArray *sepStrings = [dataString componentsSeparatedByString:@"="];
        if ([sepStrings count] == 2) {
            [_variablesDict setValue:sepStrings[1] forKeyPath:sepStrings[0]];
        }
    }
}

- (id)init
{
    self = [super init];
    if (self) {
        _variablesDict = [[NSMutableDictionary alloc] init];
    }
    return self;
}

- (NSString *)valueForVariable:(NSString *)varName {
    NSString *val = [_variablesDict valueForKeyPath:varName];
    return val;
    return nil;
}

-(NSString *)description {
    return [NSString stringWithFormat:@"Current Variables: %@", _variablesDict];
}

@end

答案 12 :(得分:0)

以下将接受的答案作为一个类别:

@implementation NSURL(Parsing)

- (NSString *)valueForParameterWithKey:(NSString *)key {
    for (NSString *var in self.parameterKeys) {
        if (var.length > key.length+1 && [[var substringWithRange:NSMakeRange(0, key.length+1)] isEqualToString:[key stringByAppendingString:@"="]]) {
            NSString *varValue = [var substringFromIndex:key.length+1];
            return varValue;
        }
    }
    return nil;
}

- (NSArray<NSString *> *)parameterKeys {
    NSScanner *scanner = [NSScanner scannerWithString:self.absoluteString];
    [scanner setCharactersToBeSkipped:[NSCharacterSet characterSetWithCharactersInString:@"&?"]];
    NSString *tempString;
    NSMutableArray *vars = [NSMutableArray new];
    [scanner scanUpToString:@"?" intoString:nil];
    while ([scanner scanUpToString:@"&" intoString:&tempString]) {
        [vars addObject:tempString.copy];
    }
    return vars;
}

@end

答案 13 :(得分:0)

所有当前答案都是特定版本或不必要的浪费。如果你只想要一个值,为什么要创建一个字典?

这是一个支持所有iOS版本的简单答案:

- (NSString *)getQueryParam:(NSString *)name  fromURL:(NSURL *)url
{
    if (url)
    {
        NSArray *urlComponents = [url.query componentsSeparatedByString:@"&"];
        for (NSString *keyValuePair in urlComponents)
        {
            NSArray *pairComponents = [keyValuePair componentsSeparatedByString:@"="];
            NSString *key = [[pairComponents firstObject] stringByRemovingPercentEncoding];

            if ([key isEqualToString:name])
            {
                return [[pairComponents lastObject] stringByRemovingPercentEncoding];
            }
        }
    }
    return nil;
}

答案 14 :(得分:-2)

最快的是:

NSString* x = [url valueForQueryParameterKey:@"x"];