Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

parse a NSURL mailto

How can I parse a mailto request ?

'mailto:[email protected][email protected]&subject=This%20is%20the%20subject&body=This%20is%20the%20body'

From this NSURL, I want to extract the recipient, the subject and the body. How should I do ?

Thanks

like image 958
Nielsou Hacken-Bergen Avatar asked Sep 05 '11 16:09

Nielsou Hacken-Bergen


3 Answers

Here is some code that will parse any URL and return a dictionary with the parameters and the associated objects in a dictionary. It works for mailto URLs, too.
Please note: This code assumes you're using 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];
}

And here is how you use it:

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:
I updated the code to work with any URL and recipients are now in the dictionary for mailto URLs.

like image 105
Fabian Kreiser Avatar answered Sep 20 '22 15:09

Fabian Kreiser


I would pull the email from that like this:

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);
like image 44
Louie Avatar answered Sep 19 '22 15:09

Louie


Since iOS 7 this is easily doable with NSURLComponents. You can create that object with:

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

Then you can get the recipient accessing the path property of NSURLComponents; and the parameters with the queryItems property. For instance, if we wanted to get the subject, something like this would do our job

let queryItems = components.queryItems as? [NSURLQueryItem]
let subject = queryItems?.filter({$0.name == "subject"}).first?.value
like image 35
toupper Avatar answered Sep 21 '22 15:09

toupper