Wednesday, August 8, 2012

How to Find MFMailComposeViewController Email Addresses


One of the missing iOS APIs is a way to find out whom did user send email to. Otherwise MFMailComposeViewController is excellent: easy to setup, easy to launch, easy to use and easy to close. You just have no idea what user was doing with it!

I really needed to know who were email recipients. There are several good reasons for this and I just had one of those. So it was time to do some experimenting!

Write this (thrice now), which is close, but just not good enough. Maybe someone can continue from here? First standard didFinishWithResult callback, nothing special there. Bit simplified for this case:
- (void)mailComposeController:(MFMailComposeViewController *)controller
didFinishWithResult:(MFMailComposeResult)result
error:(NSError*)error
{   
    if (result == MFMailComposeResultSent)
    {
        NSString *email = [self findEmailAddresses:controller.view depth:0];
        NSLog(@"%@", email);
        [self.viewController dismissModalViewControllerAnimated:YES];
    }
}
Here's the interesting code, which can be used to peek what's inside the MFMailComposeViewController blackbox (UPDATE: easier way to check view hierarchy). Pretty common view hierarchy walking code, now especially looking for text strings:
- (NSString *)findEmailAddresses:(UIView *)view depth:(NSInteger)count
{
    NSString *eAddress = nil;
    if (!view)
        return eAddress;
    
    NSMutableString *tabString = [NSMutableString stringWithCapacity:depth];
    for (int i = 0; i < depth; i++)
        [tabString appendString:@"-- "];
    NSLog(@"%@%@", tabString, view);
    
    if ([view isKindOfClass:[UITextField class]])
    {
        // MAGIC: debugger shows email address(es) in first textField
        // but only if it's about max 35 characters
        if (((UITextField *)view).text)
        {
            eAddress = [NSString stringWithString:((UITextField *)view).text];
            NSLog(@"FOUND UITextField: %@", eAddress ? eAddress : @"");
        }
    }
    
    NSArray *subviews = [view subviews];
    if (subviews) {
        for (UIView *view in subviews)
        {
            NSString *s = [self findEmailAddresses:view depth:depth+1];
            if (s) eAddress = s;
                }
    }
    
    return eAddress;
}
Problems: it finds the recipient email address(es), but only if that fits in about 35 character text string. Otherwise you find only a summary string like "aaa@aaa.aa & 2 more...". So where are the actual email addresses in this case?

No comments:

Post a Comment