2016-04-12 6 views
0

Ich habe eine Zeichenfolge, die eine URL darstellt, die in vielen Formaten vorliegen kann, und standardisieren sie so, dass sie der URL-Spezifikation entspricht.Eine saubere und robuste Methode zum Analysieren von URL-Strings in Objective C

Wenn die URL-Zeichenfolge kein Schema oder ein Schema hat, das nicht "http" oder "https" lautet, sollte ein Standardschema verwendet werden.

Ich wollte NSURLComponents verwenden, aber wenn ein Schema parst es nicht vorgesehen ist, den Host als Weg

NSURLComponents *components = [NSURLComponents componentsWithString:@"www.google.com.au"]; 
components.scheme = @"http"; 
NSLog(@"1: %@", components.path); 
NSLog(@"2: %@", components.host); 
NSLog(@"3: %@", components.string); 

testtest[2619:869020] 1: www.google.com.au 
testtest[2619:869020] 2: ((null)) 
testtest[2619:869020] 3: http:www.google.com.au <-- Invalid 

deshalb ich mit dieser Kategorie auf NSString

#define DEFAULT_SCHEME @"http" 

@implementation NSString (standardiseUrlFormat) 

- (NSString*)standardiseUrlFormat { 
    NSURLComponents *components = [NSURLComponents componentsWithString:self]; 
    BOOL hasScheme = components.scheme != nil; 

    // If no scheme or an invalid scheme is provided, default to http 
    if (!hasScheme) { 
     // We have to use string concatenation here because NSURLComponents will 
     // put the hostname as the path if there is no scheme 
     return [NSString stringWithFormat:@"%@://%@", DEFAULT_SCHEME, self]; 
    } 

    // Now we know that a scheme exists, check if it is a correct scheme 
    if (![components.scheme isEqualToString:@"http"] && 
     ![components.scheme isEqualToString:@"https"]) { 
     // Overwrite scheme if not supported 
     components.scheme = DEFAULT_SCHEME; 
    } 

    return [components string]; 
} 

@end 

Mit der folgenden Ausgabe endete

NSLog(@"1: %@", [@"http://www.google.com" standardiseUrlFormat]); 
NSLog(@"2: %@", [@"www.google.com" standardiseUrlFormat]); 
NSLog(@"3: %@", [@"https://www.google.com" standardiseUrlFormat]); 
NSLog(@"4: %@", [@"https://www.google.com/some_path" standardiseUrlFormat]); 
NSLog(@"5: %@", [@"www.google.com/some_path" standardiseUrlFormat]); 

testtest[7411:944022] 1: http://www.google.com 
testtest[7411:944022] 2: http://www.google.com 
testtest[7411:944022] 3: https://www.google.com 
testtest[7411:944022] 4: https://www.google.com/some_path 
testtest[7411:944022] 5: http://www.google.com/some_path 

Kann jemand vorschlagen eine sauberere Lösung, die nicht zwei Methoden verwendet s (NSURLComponents und String-Verkettung), um die Zeichenfolge zu erstellen?

+0

Das ist ziemlich hart. Ich bezweifle, dass die Änderung von mailto: //[email protected] zu http: //[email protected] überhaupt Sinn macht. Oder ftp, oder file: // oder grundsätzlich alles andere als http (s). – Eiko

+1

Das ist wahr, aber in diesem Fall sollte angenommen werden, dass jeder Eingabe-URL-String ein http- oder https-Schema haben sollte. –

+0

Warum nicht einfach einen String-Replace-Vorgang durchführen? Suchen Sie nach dem ersten ": //" und ersetzen Sie, was vor ihm ist mit http (solange es nicht https ist). Wenn nicht gefunden, legen Sie es an der Vorderseite ein. – Eiko

Antwort

1

Verwenden Sie keine String-Verkettung. Verwenden Sie NSURLComponents zu Formular die gewünschte NSURL; Dafür ist es da. Zum Beispiel, wenn Sie nicht mögen, was die scheme ist, setzen Sie die scheme, was Sie wollen.

BEARBEITEN Ich denke, dass ich dachte, dass, nachdem festgestellt wurde, dass dies eine hostlose URL ist, Sie sie manuell rejiggen würden, z.

let s = "www.apple.com/whatever" as NSString 
let arr = s.pathComponents 
let c = NSURLComponents() 
c.scheme = "http" 
c.host = arr[0] 
c.path = "/" + (Array(arr.dropFirst()) as NSArray).componentsJoinedByString("/") 

Aber vielleicht kann dies nicht geschehen, und das Problem ist wirklich, dass eine URL ohne eine Regelung mehr oder weniger keinen URL.

+0

Das Problem besteht darin, dass NSURLComponents URLs nicht korrekt analysiert, wenn sie kein Schema haben. Es setzt die gesamte Zeichenfolge als Pfadkomponente und lässt den Rest der Komponenten als null. Edit: Ich nehme an, ich könnte ein neues NSURLComponents-Objekt erstellen und es manuell erstellen, aber ich würde meine eigene Analyse durchführen müssen, um die Komponenten zu trennen, die es sehr viel komplexer ist. –

+0

Nun, siehe oben meinen Vorschlag, aber vielleicht gibt es keinen Ausweg ... – matt

Verwandte Themen