Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MFMailComposeViewController in a separate class

I seek to create a "Utility Email sender class" that I can use in several iPhone projects.

I created MailSender header and implementation for that purpose.

MailSender.h:

@interface MailSender : NSObject<MFMailComposeViewControllerDelegate>

- (id) initWithParent:(UIViewController*) mainController;

- (void) invokeMailSender:(NSString*) to:(NSString*) subject:(NSString*) failureTitle:(NSString*) failureMessage:(NSString*) failureCancel;

@end

MailSender.m:

#import "MailSender.h"

@implementation MailSender

MFMailComposeViewController* mailer;
UIViewController* mailParentController;

- (id) initWithParent:(UIViewController*) mainController
{
    if( self = [super init])
    {
      mailParentController = mainController;
    }
    return self;
}

- (void) invokeMailSender:(NSString*) to:(NSString*) subject:(NSString*) failureTitle:(NSString*) failureMessage:(NSString*) failureCancel;

{
    if([MFMailComposeViewController canSendMail])
    {
        mailer = [[MFMailComposeViewController alloc] init];

        mailer.mailComposeDelegate = self;

        [mailer setSubject:subject];

        NSArray *toRecipients = [NSArray arrayWithObjects:to, nil];

        [mailer setToRecipients:toRecipients];
       [mailParentController presentModalViewController:mailer animated:YES];
    }
    else
    {
        UIAlertView* alert = [[UIAlertView alloc] initWithTitle:failureTitle message:failureMessage
                                                       delegate:nil cancelButtonTitle:failureCancel otherButtonTitles: nil];

        [alert show];
    }
}

-(void)mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error
{
    // Do nothing
    [mailParentController dismissModalViewControllerAnimated:YES];
    mailer = nil;
}



@end

I called the class from a View Controller (in a button touch down action) using the following instructions:

@implementation InfoViewController

MailSender *sender;

- (IBAction)openMail:(id)sender
{
    sender = [[MailSender alloc] initWithParent:self];
    [sender invokeMailSender:@"[email protected]" :@"123" :@"123" :@"123" :@"123"];
}

.... 
@end

When I run the code, I am able to show the email views correctly. However, this is then followed by a crash. Note that I do not have a crash when using MFMailComposeViewController directly from my UIViewController (And assigning the View Controller as the delegate),

Any ideas? Sorry I am still a new to Objective C :)

like image 770
SiN Avatar asked Mar 29 '12 14:03

SiN


1 Answers

You need to retain your sender MailSender instance. It is being released after you call the invoke message.

You could do this by declaring a property named sender. E.g.

@property (strong, nonatomic) MailSender *sender;
...
@synthesize sender = _sender;
...
self.sender = [[MailSender alloc] initWithParent:self];
[self.sender invokeMailSender:@"[email protected]" :@"123" :@"123" :@"123" :@"123"];

By the way, your method declaration is a bit funny. You should name the arguments. E.g.

- (void)invokeMailSender:(NSString *)sender 
                      to:(NSString *)to 
                 subject:(NSString *)subject 
            failureTitle:(NSString *)failureTitle 
          failureMessage:(NSString *)failureMessage 
failureCancelButtonTitle:(NSString *)failureCancelButtonTitle
like image 142
Paul Hunter Avatar answered Sep 19 '22 09:09

Paul Hunter