2011-09-05 19 views

Odpowiedz

10

Oto kod, który będzie analizować dowolny adres URL i zwraca słownika z parametrów i związanych z nimi obiektów w słowniku. Działa również dla adresów URL mailto.
Uwaga: ten kod zakłada, że ​​używasz ARC!

@interface NSString (URLDecoding) 

- (NSString *) URLDecodedString; 

@end 

@implementation NSString (URLDecoding) 

- (NSString *) URLDecodedString { 
    NSString *result = (__bridge_transfer NSString *)CFURLCreateStringByReplacingPercentEscapesUsingEncoding(kCFAllocatorDefault, (__bridge CFStringRef)self, CFSTR(""), kCFStringEncodingUTF8); 
    return result; 
} 

@end 

- (NSDictionary *) parameterDictionaryFromURL:(NSURL *)url { 
    NSMutableDictionary *parameterDictionary = [[NSMutableDictionary alloc] init]; 
    if ([[url scheme] isEqualToString:@"mailto"]) { 
     NSString *mailtoParameterString = [[url absoluteString] substringFromIndex:[@"mailto:" length]]; 
     NSUInteger questionMarkLocation = [mailtoParameterString rangeOfString:@"?"].location; 
     [parameterDictionary setObject:[mailtoParameterString substringToIndex:questionMarkLocation] forKey:@"recipient"]; 

     if (questionMarkLocation != NSNotFound) { 
      NSString *parameterString = [mailtoParameterString substringFromIndex:questionMarkLocation + 1]; 
      NSArray *keyValuePairs = [parameterString componentsSeparatedByString:@"&"]; 
      for (NSString *queryString in keyValuePairs) { 
       NSArray *keyValuePair = [queryString componentsSeparatedByString:@"="]; 
       if (keyValuePair.count == 2) 
        [parameterDictionary setObject:[[keyValuePair objectAtIndex:1] URLDecodedString] forKey:[[keyValuePair objectAtIndex:0] URLDecodedString]]; 
      } 
     } 
    } 
    else { 
     NSString *parameterString = [url parameterString]; 
     NSArray *keyValuePairs = [parameterString componentsSeparatedByString:@"&"]; 
     for (NSString *queryString in keyValuePairs) { 
      NSArray *keyValuePair = [queryString componentsSeparatedByString:@"="]; 
      if (keyValuePair.count == 2) 
       [parameterDictionary setObject:[[keyValuePair objectAtIndex:1] URLDecodedString] forKey:[[keyValuePair objectAtIndex:0] URLDecodedString]]; 
     } 
    } 

    return [parameterDictionary copy]; 
} 

A oto jak go używać:

NSURL *mailtoURL = [NSURL URLWithString:@"mailto:[email protected][email protected]&subject=Greetings%20from%20Cupertino!&body=Wish%20you%20were%20here!"]; 
NSDictionary *parameterDictionary = [self parameterDictionaryFromURL:mailtoURL]; 

NSString *recipient = [parameterDictionary objectForKey:@"recipient"]; 
NSString *subject = [parameterDictionary objectForKey:@"subject"]; 
NSString *body = [parameterDictionary objectForKey:@"body"]; 

EDIT:
Zaktualizowałem kod do pracy z dowolnym adresem URL, a odbiorcy są teraz w słowniku dla adresów URL mailto.

+0

Bardzo eleganckie rozwiązanie. Podoba mi się abstrakcja. – Mundi

+0

jak mogę dołączyć do niego plik tekstowy? – Saleh

+0

To było dostać zawartość zapytania, a nie dołączyć do niego coś. –

2

chciałbym wyciągnąć z tego e-maila tak:

NSString * mailToString = @"'mailto:[email protected][email protected]&subject=This%20is%20the%20subject&body=This%20is%20the%20body'"; 

NSArray *tempArray = [mailToString componentsSeparatedByString:@"?"]; 

//get email address from array 
NSString * emailString = [[tempArray objectAtIndex:0]description]; 

//clean up string 
emailString = [emailString stringByReplacingOccurrencesOfString:@"'mailto:" withString:@""]; 

//and here is your email string 
NSLog(@"%@",emailString); 
+2

Używanie '-description' jest bardzo złą praktyką. –

+1

Dlaczego używanie '-description' jest bardzo złą praktyką? –

1

Od iOS 7 jest to łatwo wykonalne z NSURLComponents. Możesz utworzyć ten obiekt za pomocą:

if let components = NSURLComponents(URL: url, resolvingAgainstBaseURL:false) { ... 

Następnie możesz uzyskać dostęp odbiorcy do właściwości ścieżki NSURLComponents; i parametry z właściwością queryItems. Na przykład, jeśli chcemy uzyskać przedmiot, coś takiego zrobi nasza praca

let queryItems = components.queryItems as? [NSURLQueryItem] 
let subject = queryItems?.filter({$0.name == "subject"}).first?.value 
+0

Klasy 'queryItems' i' NSURLQueryItem' są dostępne tylko od wersji iOS 8.0. – Alnair

0

kategorię bibliotece NSURL za jedyne mailto: Metoda ta ma również poprawkę błędu katastrofy w odpowiedzi Fabiana powyższą gdy mailto: URL nie robi zawierają? Nie wymaga również metody kategorii URLDecodedString.

@implementation NSURL (Additions) 

- (NSDictionary *) parameterDictionaryForMailTo { 
    NSMutableDictionary *parameterDictionary = [[NSMutableDictionary alloc] init]; 
    NSString *mailtoParameterString = [[self absoluteString] substringFromIndex:[@"mailto:" length]]; 
    NSUInteger questionMarkLocation = [mailtoParameterString rangeOfString:@"?"].location; 
    if (questionMarkLocation != NSNotFound) { 
     [parameterDictionary setObject:[mailtoParameterString substringToIndex:questionMarkLocation] forKey:@"recipient"]; 
     NSString *parameterString = [mailtoParameterString substringFromIndex:questionMarkLocation + 1]; 
     NSArray *keyValuePairs = [parameterString componentsSeparatedByString:@"&"]; 
     for (NSString *queryString in keyValuePairs) { 
      NSArray *keyValuePair = [queryString componentsSeparatedByString:@"="]; 
      if (keyValuePair.count == 2) 
       [parameterDictionary setObject:[[keyValuePair objectAtIndex:1] stringByRemovingPercentEncoding] forKey:[[keyValuePair objectAtIndex:0] stringByRemovingPercentEncoding]]; 
     } 
    } 
    else { 
     [parameterDictionary setObject:mailtoParameterString forKey:@"recipient"]; 
    } 

    return [parameterDictionary copy]; 
}