analizar un mailto NSURL

¿Cómo puedo analizar una solicitud de mailto?

'mailto:someone@example.com?cc=someone_else@example.com&subject=This%20is%20the%20subject&body=This%20is%20the%20body'

De esta NSURL, quiero extraer el destinatario, el sujeto y el cuerpo. Cómo debería hacer ?

Muchas Gracias

preguntado el 05 de septiembre de 11 a las 16:09

4 Respuestas

Aquí hay un código que 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á utilizando 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 así es como se usa:

NSURL *mailtoURL = [NSURL URLWithString:@"mailto:foo@example.com?cc=bar@example.com&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 que funcione con cualquier URL y los destinatarios ahora están en el diccionario para mailto URLs.

respondido 31 mar '12, 14:03

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

¿Cómo puedo adjuntar un archivo de texto? - Saleh

Esto fue para obtener el contenido de la consulta, no para adjuntarle algo. - Fabián Kreiser

esto no consigue el destinatario - user102008

Como señala user102008, el destinatario no está contenido en la parte de consulta de la URL. - Sixten Otto

Sacaría el correo electrónico de eso de esta manera:

NSString * mailToString = @"'mailto:someone@example.com?cc=someone_else@example.com&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);

Respondido el 05 de Septiembre de 11 a las 20:09

Usar -description es una muy mala práctica. - Fabián Kreiser

Por qué usar -description es muy mala practica? - Valeriy Van

Desde iOS 7, esto se puede hacer fácilmente con NSURLComponents. Puede crear ese objeto con:

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

Entonces puede hacer que el destinatario acceda a la propiedad de ruta de NSURLComponents; y los parámetros con la propiedad queryItems. Por ejemplo, si quisiéramos obtener el tema, algo como esto haría nuestro trabajo

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

contestado el 07 de mayo de 15 a las 12:05

queryItems y NSURLQueryItem Sin embargo, la clase en sí solo está disponible desde iOS 8.0. - Antonio Favata

Categoría NSURL solo para mailto: este método también tiene una solución para un error de bloqueo en la respuesta de Fabian anterior cuando mailto: url 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];
}

contestado el 19 de mayo de 16 a las 23:05

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.