2009-12-27 4 views
12

Gibt es irgendwelche Standard-Objekte oder Funktionen, um eine NSURL-Komponenten zu analysieren? Natürlich könnte ich einen schreiben, aber warum erfinde ich das Rad neu?Parse NSURL Pfad und Abfrage (iPhoneOS)

[NSURL path] wird eine NSString wie "argX=x&argY=y&argZ=z" zurückkehren Was ich eher ein Wörterbuch ist mit {@"argX" => @"x", @"argY" => @"y", @"argZ" = @"z"}

Für den Weg bevölkert würde zurückkommen, die wie eine Zeichenfolge zurückgibt „/ PARTA/TeilB/PARTC“, würde ich lieber erhalten ein Array mit der Struktur {[0] => @"partA", [1] => @"partB", [2] => @"partC"}

ich weiß, das ist eine ziemlich spezifische fragen, aber es scheint, wie etwas, was viele Menschen wollen würde ...

EDIT - Dies ist für iphoneos! Offenbar hat NSURL verschiedene Funktionen auf Mac OS

+0

Gute Frage. Meinst du: Wenn die URL "/ partA/partB/partC" ist, willst du "0 => partA, 1 => partB, 2 => partC". Wenn die URL "/ foo? PartA = A & partB = B" lautet, möchten Sie "partA => A, partB => B". Was ist, wenn die URL "/ partA/partB/partC? Foo = bar & ooga = booga" ist? In einem Beispiel wird die wichtige Information, die benötigt wird, um die fragliche Entität zu identifizieren, in einer Abfragestring übergeben. In dem anderen Beispiel wird die identifizierende Information im Pfad selbst rest-style übergeben. –

+0

Ich meine, ich möchte den Pfad und die Abfrage getrennt analysieren. Es sollte nicht eine Funktion sein, die diese beiden Aufgaben kombiniert. Sehen Sie den Code, den ich zur Klärung unten angegeben habe. Wenn jemand mit einer bestehenden Implementierung antwortet, werde ich das gerne akzeptieren. – DougW

+0

Eine Sache zu beachten ist, dass dies eine absolut gültige Abfragezeichenfolge ist: "x = 1 & x = 0 & x = foo", also ein NSDictionary möglicherweise nicht die beste Darstellung (außer Sie Arrays als Werte verwenden). – n8gray

Antwort

9

Sie möchten vielleicht pathComponents betrachten, die ein Array der Komponenten der URL zurückgibt. Erfahren Sie mehr here.

+0

Ich glaube nicht, dass dies auf der iPhone-Version des SDK verfügbar ist. Ich hätte klarstellen sollen, dass ich an iPhone OS arbeite. – DougW

+2

[NSString pathComponents] ist in den Cocoa und Cocoa Touch APIs verfügbar. Auf dem iPhone können Sie [NSURL pathComponents] von OS X 10.6 mit [[NSURL path] pathComponents] imitieren. –

+0

Ah perfekt, das ist was ich gesucht habe, zumindest für den Wegabschnitt! – DougW

2

Wenn Sie sich entschließen, eine schreiben (Ich bin nicht sicher, dass es bestehende Verfahren zur Herstellung der Komponenten erhalten Sie wollen), sollten Sie NSString die componentsSeparatedByString verwenden.

+0

Danke, rettete mir ein bisschen von der Arbeit! – DougW

12

In Ordnung, ich habe antsy und schrieb eine Lösung für die Erweiterung NSString durch Kategorien. Ich habe das noch nicht getestet, aber wenn Sie es verwenden wollen, gehen Sie dafür.

NSMutableDictionary *parsedQuery = [[myNSURL query] explodeToDictionaryInnerGlue:@"=" [email protected]"&"] 

Für den Pfad Teil des NSURL Parsing (dh @ "/ PARTA/TeilB/PARTC"), das nur nennen:

NSArray *parsedPath = [[nyNSURL path] componentsSeperatedByString:@"/"]; 

@interface NSString (ParseCategory) 
- (NSMutableDictionary *)explodeToDictionaryInnerGlue:(NSString *)innerGlue outterGlue:(NSString *)outterGlue; 
@end 

@implementation NSString (ParseCategory) 

- (NSMutableDictionary *)explodeToDictionaryInnerGlue:(NSString *)innerGlue outterGlue:(NSString *)outterGlue { 
    // Explode based on outter glue 
    NSArray *firstExplode = [self componentsSeparatedByString:outterGlue]; 
    NSArray *secondExplode; 

    // Explode based on inner glue 
    NSInteger count = [firstExplode count]; 
    NSMutableDictionary *returnDictionary = [NSMutableDictionary dictionaryWithCapacity:count]; 
    for (NSInteger i = 0; i < count; i++) { 
     secondExplode = [(NSString *)[firstExplode objectAtIndex:i] componentsSeparatedByString:innerGlue]; 
     if ([secondExplode count] == 2) { 
      [returnDictionary setObject:[secondExplode objectAtIndex:1] forKey:[secondExplode objectAtIndex:0]]; 
     } 
    } 

    return returnDictionary; 
} 

@end 

es so genannt

Beachten Sie, dass parsedPath [0] wegen der führenden /! -Liste eine leere Zeichenfolge ist.

EDIT - Hier ist eine Kategorie-Erweiterung zu NSURL für Ihre Nutzung Vergnügen. Es entfernt das ursprüngliche "/", so dass Sie keinen leeren 0-Index haben.

@implementation NSURL (ParseCategory) 

- (NSArray *)pathArray { 
    // Create a character set for the slash character 
    NSRange slashRange; 
    slashRange.location = (unsigned int)'/'; 
    slashRange.length = 1; 
    NSCharacterSet *slashSet = [NSCharacterSet characterSetWithRange:slashRange]; 

    // Get path with leading (and trailing) slashes removed 
    NSString *path = [[self path] stringByTrimmingCharactersInSet:slashSet]; 

    return [path componentsSeparatedByCharactersInSet:slashSet]; 
} 

- (NSDictionary *)queryDictionary { 
    NSDictionary *returnDictionary = [[[[self query] explodeToDictionaryInnerGlue:@"=" outterGlue:@"&"] copy] autorelease]; 
    return returnDictionary; 
} 

@end 
+0

Ich bin mir nicht sicher, warum jemand das abgelehnt hat ... das bringt mir bei, Code zu teilen, denke ich? Es würde mich nicht stören, wenn du einen Kommentar hinterlassen hättest, aber ich nehme an, du bist ein zufälliger Troll. Hallo Troll. – DougW

+4

Danke, das funktioniert gut für mich.Beachten Sie, dass Sie möglicherweise auch Ihre individuellen Abfragezeichenfolgen URL-decodieren müssen. Ich benutze den folgenden Code dafür, zuerst auf Prozent-Escapes zu achten, dann "+" durch Leerzeichen zu ersetzen, was das erste leider nicht tut: [[Wert stringByReplacingPercentEscapesUsingEncoding: NSUTF8StringEncoding] stringByReplacingOccurrencesOfString: @ "+ "withString: @" "] –

+0

Sehr willkommen. Und ja, ich habe Sachen der Kodierung/Dekodierung aus diesen Funktionen herausgelassen. – DougW

5

Heres, was ich die Query-String-

// Parse the individual parameters 
// parameters = @"hello=world&foo=bar"; 
NSMutableDictionary *dictParameters = [[NSMutableDictionary alloc] init]; 
NSArray *arrParameters = [parameters componentsSeparatedByString:@"&"]; 
for (int i = 0; i < [arrParameters count]; i++) { 
    NSArray *arrKeyValue = [[arrParameters objectAtIndex:i] componentsSeparatedByString:@"="]; 
    if ([arrKeyValue count] >= 2) { 
     NSMutableString *strKey = [NSMutableString stringWithCapacity:0]; 
     [strKey setString:[[[arrKeyValue objectAtIndex:0] lowercaseString] stringByReplacingPercentEscapesUsingEncoding: NSUTF8StringEncoding]]; 
     NSMutableString *strValue = [NSMutableString stringWithCapacity:0]; 
     [strValue setString:[[[arrKeyValue objectAtIndex:1] stringByReplacingOccurrencesOfString:@"+" withString:@" "] stringByReplacingPercentEscapesUsingEncoding: NSUTF8StringEncoding]]; 
     if (strKey.length > 0) [dictParameters setObject:strValue forKey:strKey]; 
    } 
} 
NSLog(@"Parameters: %@", dictParameters); 
2

in iOS eingeführt zu analysieren verwenden 8 und OS X 10.10 ist NSURLQueryItem, die verwendet werden können Abfragen zu erstellen. Aus der Dokumentation auf NSURLQueryItem:

Ein NSURLQueryItem Objekt für ein Element in der Abfrage Teil einer URL ein einziges Name/Wert-Paar darstellt. Sie verwenden Abfrageelemente mit der queryItems-Eigenschaft eines NSURLComponents-Objekts.

Sie die Abfrageelemente aus einer URL, indem zuerst NSURLComponents abrufen können:

NSURL *url = [NSURL URLWithString:@"http://stackoverflow.com?q=ios&count=10"]; 
NSURLComponents *components = [NSURLComponents componentsWithURL:url 
               resolvingAgainstBaseURL:YES]; 
for (NSURLQueryItem *item in components.queryItems) { 
    NSLog(@"name: %@, value: %@", item.name, item.value); 
} 
// name: q, value: ios 
// name: count, value: 10 

anzumerken, dass sie für -queryItems Rückgabewert ist ein Array, kein Wörterbuch. Dies liegt daran, dass das folgende eine gültige URL ist. Beachten Sie die zwei identischen "Schlüssel" foo.

http://google.com?foo=bar&foo=baz

Um eine URL per Abfrageelemente, verwenden Sie die benannten Initialisierer queryItemWithName:value: und dann fügen Sie sie zu NSURLComponents schaffen eine NSURL zu erzeugen. Beispiel:

NSString *urlString = @"http://stackoverflow.com"; 
NSURLComponents *components = [NSURLComponents componentsWithString:urlString]; 
NSURLQueryItem *search = [NSURLQueryItem queryItemWithName:@"q" value:@"ios"]; 
NSURLQueryItem *count = [NSURLQueryItem queryItemWithName:@"count" value:@"10"]; 
components.queryItems = @[ search, count ]; 
NSURL *url = components.URL; // http://stackoverflow.com?q=ios&count=10 

Beachten Sie, dass das Fragezeichen und das Und-Zeichen automatisch behandelt werden. ein NSURL aus einem Wörterbuch von Parametern zu erstellen ist so einfach wie:

NSDictionary *queryDictionary = @{ @"q": @"ios", @"count": @"10" }; 
NSMutableArray *queryItems = [NSMutableArray array]; 
for (NSString *key in queryDictionary) { 
    NSURLQueryItem *item = [NSURLQueryItem queryItemWithName:key 
                 value:queryDictionary[key]]; 
    [queryItems addObject:item]; 
} 
components.queryItems = queryItems; 

ich auch eine Blog-Post mit mehr Details geschrieben habe, Building NSURLs with NSURLQueryItems.

+0

Cool! Nur eine Anmerkung an Entwickler - wenn Sie doppelte GET-Parameter verwenden, sind Sie in einer Welt der Verletzung. Es gibt keine definierte Spezifikation für den Umgang mit diesen und verschiedene Sprachen/Plattformen bilden ihre eigenen Regeln. Siehe http://stackoverflow.com/questions/1746507/authoritative-position-of-duplicate-http-get-query-keys – DougW

Verwandte Themen