Search code examples
iphoneobjective-ciosxcodemfmailcomposeviewcontroller

iOS: MFMailComposeViewController not working on model


Having trouble with the MFMessageComposeViewController. The situation goes like this:

I am creating a model that will implement the MFMessageComposeViewController instead of doing it in the ViewController directly. Now, when I implement the presentModalViewController:: method, it works fine (the mail.app interface appears) but when I click the cancel / send button in the mail.app interface, it will not dismiss the mail.app..

Its like something like this:

a method snippet from MSGViewController that implements the send mail model:

- (IBAction)openEmail:(id)sender {
    Messaging *mail = [[Messaging alloc]initWithModal:self];
    [mail emailInvitation:@"Eventz Date" eventAt:@"Eventz Location" withImage:nil];
    [self.sendingStatus setText:mail.sendingStatus];
}

my model for implementing the Messaging:

Messaging.h

#import <Foundation/Foundation.h>
#import <MessageUI/MessageUI.h>

@interface Messaging : NSObject <MFMailComposeViewControllerDelegate, MFMessageComposeViewControllerDelegate>

@property (nonatomic, copy) NSString *sendingStatus;
@property (nonatomic, retain) id modal;

- (id)initWithModal:(id)modal;
- (void)emailInvitation:(NSString *)eventDate eventAt:(NSString *)eventLocation withImage:(UIImage *)imageAttachment;

@end

Messaging.m

#import "Messaging.h"

@implementation Messaging

@synthesize sendingStatus = _sendingStatus;
@synthesize modal = _modal;

- (id)initWithModal:(id)modal{
    self = [super init];
    self.modal = modal;
    return self;
}



- (void)emailInvitation:(NSString *)eventDate eventAt:(NSString *)eventLocation withImage:(UIImage *)imageAttachment{

    MFMailComposeViewController *mailer = [[MFMailComposeViewController alloc] init];

    if ([MFMailComposeViewController canSendMail]){      
        mailer.mailComposeDelegate = self;

        [mailer setSubject:@"Event Invitation"];
        [mailer setMessageBody:@"message body"] isHTML:NO];

        if(imageAttachment != nil){
            NSData *imageData = UIImagePNGRepresentation(imageAttachment);
            [mailer addAttachmentData:imageData mimeType:@"image/png" fileName:@"imageFileName"];
        }

        [self.modal presentModalViewController:mailer animated:YES];
        return;
    }

    [self deviceDoNotSupportMessaging];        
}

- (void)mailComposeController:(MFMailComposeViewController*)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error
{
    NSLog(@"called");
    switch (result)
    {
        case MFMailComposeResultCancelled:
            self.sendingStatus = @"Mail sending cancelled.";
            break;
        case MFMailComposeResultSaved:
            self.sendingStatus = @"Mail saved.";
            break;
        case MFMailComposeResultSent:
            self.sendingStatus = @"Mail sent.";
            break;
        case MFMailComposeResultFailed:
            self.sendingStatus = @"Mail sending failed.";
            break;
        default:
            self.sendingStatus = @"Mail not sent.";
            break;
    }

    [controller dismissModalViewControllerAnimated:YES];
}

BTW, the NSLog(@"called"); in the .m is not called actually... Can someone have any suggestion? thanks.. :D


Solution

  • I am wondering why you aren't getting an error when your pointer get dealloc'd. I used your code and got that error right away when instantiating the Message class:

    Messaging *mail = [[Messaging alloc]initWithModal:self];
    

    So I changed one thing, I made mail a Strong Property in my calling class:

    @property (strong, nonatomic) Messaging *mail;
    

    And then called it this way:

    mail = [[Messaging alloc]initWithModal:self];
                    [mail emailInvitation:@"Eventz Date" eventAt:@"Eventz Location" withImage:nil];
                    NSLog(@"Called the emailInvitation");
    

    The log statements were called and I even made sure that the MailComposer got back the proper response:

    - (void)mailComposeController:(MFMailComposeViewController*)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error
    {
        NSLog(@"called");
        switch (result)
        {
            case MFMailComposeResultCancelled:
                self.sendingStatus = @"Mail sending cancelled.";
                NSLog(@"Mail Cancelled");
                break;
            case MFMailComposeResultSaved:
                self.sendingStatus = @"Mail saved.";
                NSLog(@"Mail Saved");
                break;
            case MFMailComposeResultSent:
                self.sendingStatus = @"Mail sent.";
                NSLog(@"Mail Sent");
                break;
            case MFMailComposeResultFailed:
                self.sendingStatus = @"Mail sending failed.";
                NSLog(@"Mail Failed");
                break;
            default:
                self.sendingStatus = @"Mail not sent.";
                NSLog(@"Mail Not Sent");
                break;
        }
    
        [controller dismissModalViewControllerAnimated:YES];
    }
    

    And it did.

    BTW - I love the way you are doing this. This is the way OOP should be done.