0

I am trying to send email from within my iOS app.

The idea is to have one class SendMessage which all classes use to send email from within the app. It is a subclass of NSObject and is a MFMailComposeViewControllerDelegate

This is what the SendMessage class looks like

@implementation SendMessage

- (void) sendEmailFromViewController : (UIViewController *)viewController withSubject : (NSString *) subject withRecipient : (NSString *)recipient withMessage : (NSString *)message withCompletionBlock : (void(^)(void))completionBlock withFailure : (void(^)(void))failure {

    self.viewController = viewController;

    if (![MFMailComposeViewController canSendMail]){
        if (failure)
            failure();
    }
    else {
        MFMailComposeViewController *messageController = [[MFMailComposeViewController alloc] init];
        messageController.mailComposeDelegate = self.viewController;
        [messageController setSubject:subject];
        [messageController setToRecipients:[NSArray arrayWithObject:recipient]];
        [messageController setMessageBody:message isHTML:NO];

        [self.viewController presentModalViewController:messageController animated:YES];

    }
}

-(void) mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error {
    [self.viewController dismissViewControllerAnimated:YES completion:nil];
}

@end

I am trying to call the class using:

-(void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    if (indexPath.row == 3) {
        SendMessage *sendFeedback = [[SendMessage alloc] init];
        [sendFeedback sendEmailFromViewController:self withSubject:@"App Feedback" withRecipient:@"ashisha@moj.io" withMessage:@"This is app feedback" withCompletionBlock:nil withFailure:nil];
    }
}

The problem is that although I am able to send the email, the delegate method is not being called. How do I fix it ?

Ashish Agarwal
  • 14,555
  • 31
  • 86
  • 125

2 Answers2

1

Your delegate is the UIViewController, so implement the mailComposeController:didFinishWithResult:error delegate method there.

gabbler
  • 13,626
  • 4
  • 32
  • 44
  • I just changed the SendMessage to be a subclass of UIViewController and set the messageController.mailComposeDelegate = self – Ashish Agarwal Feb 07 '15 at 06:46
  • You can implement the method in the view controller which has `didSelectRowAtIndexPath` method. You don't have to subclass it, and setting delegate to self won't work because `sendFeedback` is an instance variable and will be released out of scope. – gabbler Feb 07 '15 at 06:49
  • I changed the instance variable to a property. It works now. Thanks – Ashish Agarwal Feb 07 '15 at 07:01
0

I think the problem is that your object sendFeedback is released at the end of the block.

The best solution is to create singleton object and than use it

In the SendMessage.h file add

+ (instancetype) sharedManager;

In the SendMessage.m file add

+ (instancetype) sharedManager{
    static SendMessage* instance = nil;
    if(!instance){
        instance = [[SendMessage alloc] init];
    }
    return instance;
}

Than you can use your singleton anywhere in the code

-(void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    if (indexPath.row == 3) {
        SendMessage *sendFeedback = [SendMessage sharedManager];
        [sendFeedback sendEmailFromViewController:self withSubject:@"App Feedback" withRecipient:@"ashisha@moj.io" withMessage:@"This is app feedback" withCompletionBlock:nil withFailure:nil];
    }
}

Also messageController.mailComposeDelegate must be set to self

3CC
  • 502
  • 3
  • 11