NSURL为参数string中的键提取单个值

我有一个NSURL:

serverCall?X = A&Y = B&Z = C

什么是最快和最有效的方式来获得y的价值?

谢谢

更新:

自从2010年写这篇文章以来,似乎苹果已经为此发布了一套工具。 请参阅下面的答案。

老学校解决scheme:

那么我知道你说“ 最快的方法 ”,但是在我开始用NSScanner做testing之后,我无法停下来。 尽pipe这不是最短的方法,但是如果您打算使用这个function,那么这个方法确实很方便。 我创build了一个使用URLParser获取这些variables的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 

*如果你不喜欢复制和粘贴,你可以下载源文件 – 我在这里做了一个快速的博客文章。

这么多的自定义urlparsing器,记得NSURLComponents是你的朋友!

这里是一个例子,我拉出一个url的编码参数为“page”

迅速

 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)") 

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

“为什么要重新发明轮子!” – 聪明的人

我很确定你必须自己parsing它。 但是,这不是太糟糕:

 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"]); 

我一直在使用这个类别: 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"]; 

在Swift中,您可以使用NSURLComponents将NSURL的查询stringparsing为[AnyObject]。

然后,您可以从中创build一个字典(或直接访问这些项目)以获取键/值对。 作为一个例子,这是我用来parsingNSURLvariablesurl:

 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"]) 

您可以使用Google Toolbox for Mac。 它将一个函数添加到NSString将查询string转换为字典。

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

它像一个魅力

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

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

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

示例用法:

 let url = NSURL(string: "http://google.com?test=dolphins") if let testParam = url.params["test"] { print("testParam: \(testParam)") } 

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

https://github.com/nicklockwood/RequestUtils

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

 #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 

我build议看看getResourceValue:forKey:error: forKey参数将是y ,我相信。

你可以做到这一点:

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

它像这样返回字典:Key = value

为了更好的内存pipe理和效率,我编辑了Dimitris的代码。 此外,它在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 

这是接受的答案作为一个类别:

 @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 

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

这是一个简单的答案,支持所有的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; } 

最快的是:

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