NSURL in einem Parameter-String einen einzelnen Wert für einen Schlüssel herausziehen

StackOverflow https://stackoverflow.com/questions/2225814

  •  19-09-2019
  •  | 
  •  

Frage

Ich habe eine NSURL:

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

Was ist der schnellste und effizienteste Weg, um den Wert von y zu bekommen?

Danke

War es hilfreich?

Lösung

UPDATE:

Seit 2010, als dies geschrieben wurde, wie es scheint Apple eine Reihe von Tools für diesen Zweck freigegeben hat. Bitte beachten Sie die Antworten unten für diejenigen.

Alt-Schule Lösung:

Nun, ich weiß, Sie sagten „ der schnellste Weg, “, aber nachdem ich tun einen Test mit NSScanner begann stoppen konnte ich einfach nicht. Und während es nicht der kürzeste Weg ist, ist es sicher praktisch, wenn Sie verwenden möchten, die viel bieten. Ich habe eine URLParser Klasse, die diese Vars mit einem NSScanner bekommt. Die Verwendung ist ein einfaches Beispiel:

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

Und die Klasse, tut dies die folgenden (* Quelldateien am unteren Rande der Post):

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

* wenn Sie nicht kopieren und einfügen und wie Sie können nur die Quelldateien herunterladen - Ich habe eine schnelle Blog-Post über das hier .

Andere Tipps

So viele individuelle URL-Parser hier, denken Sie daran NSURLComponents ist dein Freund!

Hier ist ein Beispiel, wo ich für „Seite“ eine URL codierten Parameter herausziehen

Swift

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

"Warum das Rad neu erfinden!" - Jemand intelligente

Ich bin mir ziemlich sicher, dass Sie es selbst zu analysieren haben. Allerdings ist es nicht so schlecht:

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

In Swift können Sie NSURLComponents verwenden, um den Query-String eines NSURL in einen [ANYOBJECT] zu analysieren.

Sie können dann ein Wörterbuch von ihm (oder nehmen Sie die Elemente direkt zugreifen) an den Schlüssel / Wert-Paare zu erhalten. Als Beispiel ist es das, was ich eine NSURL Variable URL zu analysieren bin mit:

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

Ich habe diese Kategorie wurden: ein. https://github.com/carlj/NSURL-Parameters

Es ist klein und einfach zu bedienen:

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

Sie können Google Toolbox for Mac verwenden. Es fügt eine Funktion NSString zu Query-String in ein Wörterbuch zu konvertieren.

http://code.google.com/p/google-toolbox -für-mac /

Es funktioniert wie ein Charme

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

Hier ist ein Swift 2.0-Erweiterung, die einen einfachen Zugriff auf Parameter bestimmt:

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

Verwendungsbeispiel:

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

Ich schrieb eine einfache Kategorie NSString / NSURL zu erweitern, die Sie Parameter einzeln extrahieren URL Abfrage lässt oder als Wörterbuch von Schlüssel / Wert-Paare:

https://github.com/nicklockwood/RequestUtils

Ich habe es ein Kategorie-Verfahren basierend auf @Dimitris Lösung

#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

Sie können das tun, einfach:

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

Es zurückkehren Wörterbuch wie es: Key = Wert

I edited Dimitris' Code leicht für eine bessere Speicherverwaltung und Effizienz. Außerdem funktioniert es in 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

Alle aktuellen Antworten sind versionsspezifische oder unnötig verschwenderisch. Warum ein Wörterbuch erstellen, wenn Sie nur einen Wert wollen?

Hier ist eine einfach Antwort, die alle iOS-Versionen unterstützt:

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

Schnellste ist:

NSString* x = [url valueForQueryParameterKey:@"x"];
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top