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¶mB=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查询参数,或者作为键/值对的字典:
我使用了基于@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"];