NSURL saca un valor único para una clave en una cadena de parámetros

Tengo un NSURL:

serverCall? x = a & y = b & z = c

¿Cuál es la forma más rápida y eficiente de obtener el valor de y?

Gracias

ACTUALIZAR:

Desde 2010, cuando se escribió esto, parece que Apple ha lanzado un conjunto de herramientas para ese fin. Por favor, mira las respuestas a continuación para aquellos.

Solución de la vieja escuela:

Bien, sé que dijiste ” la manera más rápida “, pero después de que empecé a hacer una prueba con NSScanner no pude parar. Y si bien no es el camino más corto, es muy útil si planea usar esa función mucho. URLParser una clase URLParser que obtiene estos vars usando un NSScanner . El uso es simple como:

 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 

Y la clase que hace esto es la siguiente (* archivos de origen en la parte inferior de la publicación):

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 

* Si no te gusta copiar y pegar puedes simplemente descargar los archivos fuente. Hice una publicación rápida sobre este tema aquí .

Tantos analizadores de URL personalizados aquí, ¡recuerda que NSURLComponents es tu amigo!

Aquí hay un ejemplo donde saco un parámetro codificado en url para “página”

Rápido

 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 objective

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

“¡Por qué reinventar la rueda!” – Alguien inteligente

Estoy bastante seguro de que tienes que analizarlo tú mismo. Sin embargo, no es tan malo:

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

En Swift puede usar NSURLComponents para analizar la cadena de consulta de un NSURL en un [AnyObject].

A continuación, puede crear un diccionario a partir de él (o acceder a los elementos directamente) para obtener los pares clave / valor. Como ejemplo, esto es lo que estoy usando para analizar una url variable de NSURL:

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

He estado usando esta categoría: https://github.com/carlj/NSURL-Parameters .

Es pequeño y fácil de usar:

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

Puede usar Google Toolbox para Mac. Agrega una función a NSString para convertir la cadena de consulta a un diccionario.

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

Funciona a las mil maravillas

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

Aquí hay una extensión de Swift 2.0 que proporciona acceso simple a los parámetros:

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

Uso de muestra:

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

Escribí una categoría simple para extender NSString / NSURL que le permite extraer parámetros de consulta URL individualmente o como un diccionario de pares clave / valor:

https://github.com/nicklockwood/RequestUtils

Lo hice usando un método de categoría basado en la solución @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 

Recomiendo mirar getResourceValue:forKey:error: El parámetro forKey será y , creo.

Puedes hacer eso fácil:

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

Devuelve un diccionario como este: clave = valor

Edité el código de Dimitris un poco para una mejor gestión de la memoria y la eficiencia. Además, funciona en 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 

Aquí está la respuesta aceptada como categoría:

 @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 *)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 

Todas las respuestas actuales son específicas de la versión o innecesariamente derrochadoras. ¿Por qué crear un diccionario si solo quieres un valor?

Aquí hay una respuesta simple que admite todas las versiones de 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; } 

Lo más rápido es:

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