user1415780
user1415780

Reputation: 1153

unable to load the mail client in iOS

I noticed that I am using the mail functionality several time so I decided to make an independent Class for functions that get repeated several time instead of copy-pasting the code several times

the class get successfully called and the e-mail function get successfully called as well but the e-mail client of the phone does not appear after the function is called

here is my code

in the main class I do the following call

-(void)emailFunction{
...

CommonlyUsed Email = [[CommonlyUsed alloc] init];
[Email sendMail:receipient :CC :BCC :subject :body];

...
}

in my CommonlyUsed.h I have the following IDEs called :

#import <UIKit/UIKit.h>
#import <MessageUI/MFMailComposeViewController.h>
#import <MessageUI/MessageUI.h>


@interface CommonlyUsed : UIViewController <MFMailComposeViewControllerDelegate>{

in CommonlyUsed.m I have the following :

-(void)sendMail:(NSString*)receipient:(NSString*)cc:(NSString*)bcc:(NSString*)subject:(NSString*)body{

 MFMailComposeViewController *composer = [[MFMailComposeViewController alloc] init];
    [ composer setMailComposeDelegate:self];

 if ( [MFMailComposeViewController canSendMail]){
if (receipient) {
            [composer setToRecipients:[NSArray arrayWithObjects:receipient, nil]];
        }

        if (cc) {
            [composer setCcRecipients:[NSArray arrayWithObjects:receipient, nil]];
        }

        if (bcc) {
            [composer setBccRecipients:[NSArray arrayWithObjects:receipient, nil]];
        }

        if (subject) {
             [composer setSubject:subject];
        }

 [composer setMessageBody:body isHTML:HTMLBody];

        [composer setModalTransitionStyle:UIModalTransitionStyleCrossDissolve];

        [self presentModalViewController:composer animated:YES];
        }
}

- (void)mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error {
    if(error){
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"error" message:[NSString stringWithFormat:@"error %@", [error description]] delegate:nil cancelButtonTitle:@"dismiss" otherButtonTitles:nil, nil];
        [alert show];
        [self dismissModalViewControllerAnimated:YES];
    }
    else{
        [self dismissModalViewControllerAnimated:YES];
    }

    }

the code compiles and runs without errors what am I missing ??

Upvotes: 0

Views: 224

Answers (2)

Ecarrion
Ecarrion

Reputation: 4950

Instead of doing this:

[self presentModalViewController:composer animated:YES];

do this:

[[[[[UIApplication sharedApplication] delegate] window] rootViewController] presentModalViewController:composer animated:YES];

or this:

[[[[UIApplication sharedApplication] keyWindow] rootViewController] presentModalViewController:composer animated:YES];

Your class Email is not currently an active view controller so it can't present a modal view controller, you need to use an active one, like the rootViewController of the main UIWindow.

EDIT:

If your using ARC by the time the emailClient gets dismissed your object(delegate) would have been removed from memory, so a solution is to make the CommonlyUsed class a Singleton:

+(CommonlyUsed *)sharedInstance {

    static CommonlyUsed * cu = nil;

    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{

        cu = [[CommonlyUsed alloc] init];

    });

    return cu;
}

So you would use it this way:

CommonlyUsed * email = [CommonlyUsed sharedInstance];
[email sendMail:receipient :CC :BCC :subject :body];

Upvotes: 2

Martin R
Martin R

Reputation: 539795

You send presentModalViewController: to your instance Email of class CommonlyUsed, but this instance is not a view controller in the view hierarchy.

You must send presentModalViewController: to your currently active view controller.

Upvotes: 2

Related Questions