2011-09-05 13 views

Respuesta

10

Aquí hay un código que va a analizar cualquier URL y devolver un diccionario con los parámetros y los objetos asociados en un diccionario. Funciona para mailto URL, también.
Tenga en cuenta: Este código asume que está usando 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]; 
} 

Y aquí es cómo lo usa:

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:
Actualicé el código para trabajar con cualquier URL y los destinatarios ahora están en el diccionario para las URL mailto.

+0

Solución muy elegante. Me gusta la abstracción. – Mundi

+0

¿cómo puedo adjuntar un archivo de texto con él? – Saleh

+0

Esto era para obtener el contenido de la consulta, no adjuntarle nada. –

2

Me tire el correo electrónico de que de esta manera:

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

Usar '-description' es una práctica muy mala. –

+1

¿Por qué usar '-description' es una práctica muy mala? –

1

Desde iOS 7 Esto es fácilmente factible con NSURLComponents. Puede crear ese objeto con:

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

entonces se puede obtener el destinatario para acceder a la propiedad de la ruta NSURLComponents; y los parámetros con la propiedad queryItems. Por ejemplo, si queríamos conseguir el objeto, algo como esto sería hacer nuestro trabajo

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

'queryItems' y la clase' NSURLQueryItem' en sí misma solo están disponibles desde iOS 8.0. – Alnair

0

categoría NSURL por sólo mailto: Este método también tiene una corrección para un error grave en la respuesta de Fabian anterior cuando mailto: url doesn no contiene un? Tampoco requiere el método de categoría 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]; 
}