18

I use this block to send message to the contacts, after sending, the back button is there, but when I touch it nothing happens. Please help me out :)

-(IBAction) InviteIt:(id) sender{


    if ([MFMessageComposeViewController canSendText]) {
        MFMessageComposeViewController *messageComposer =
        [[MFMessageComposeViewController alloc] init];
        messageComposer.messageComposeDelegate = self;
        NSString *message = @"You have more body buddies than you think at: http://www.itunes.com/app/JoyChain ";
        [messageComposer setBody:message];
        messageComposer.recipients = [NSArray arrayWithObjects:_itsnum, nil];
        messageComposer.messageComposeDelegate = self;
        [self presentViewController:messageComposer animated:YES completion:nil];

    }

}
  • comment on naming convention only: the methods' names should be with lowercase initial, like `–inviteIt:` – holex Jun 25 '15 at 08:01

6 Answers6

24

Did you forget to implement mailComposeController:didFinishWithResult: ?...

- (void) mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error
{
    switch (result)
    {
        case MFMailComposeResultCancelled:
            NSLog(@"Mail cancelled");
            break;
        case MFMailComposeResultSaved:
            NSLog(@"Mail saved");
            break;
        case MFMailComposeResultSent:
            NSLog(@"Mail sent");
            break;
        case MFMailComposeResultFailed:
            NSLog(@"Mail sent failure: %@", [error localizedDescription]);
            break;
        default:
            break;
    }

    // Close the Mail Interface
    [controller dismissViewControllerAnimated:YES completion:nil];
}

From apple documentation:

// The mail compose view controller delegate method
- (void)mailComposeController:(MFMailComposeViewController *)controller
              didFinishWithResult:(MFMailComposeResult)result
              error:(NSError *)error
{
    [self dismissModalViewControllerAnimated:YES];
}

But you can handle all cases depend on your goal ...

0yeoj
  • 4,390
  • 3
  • 21
  • 40
Doro
  • 2,395
  • 2
  • 12
  • 25
  • haha, good! I will accept your answer though it should be like this: `code`- (void)messageComposeViewController:(MFMessageComposeViewController *)controller didFinishWithResult:(MessageComposeResult)result { [self dismissModalViewControllerAnimated:YES]; if (result == MessageComposeResultCancelled) NSLog(@"Message cancelled"); else if (result == MessageComposeResultSent) NSLog(@"Message sent"); else NSLog(@"Message failed"); } –  Jun 25 '15 at 07:51
  • ok, you may organise you logic as you want :) hm, this is working snippet from my project - and as recommended apple https://developer.apple.com/library/prerelease/ios/documentation/UserExperience/Conceptual/SystemMessaging_TopicsForIOS/Articles/SendingaMailMessage.html – Doro Jun 25 '15 at 07:54
7

Here's the answer for Swift 4, iOS 11

func mailComposeController(_ controller: MFMailComposeViewController, didFinishWith result: MFMailComposeResult, error: Error?) {
        print("Emailing attempt, error="+(error?.localizedDescription)!)        
        switch (result){
        case MFMailComposeResult.cancelled:
            print("Mail cancelled");
            break;
        case MFMailComposeResult.saved:
            print("Mail saved");
            break;
        case MFMailComposeResult.sent:
            print("Mail sent");
            break;
        case MFMailComposeResult.failed:
            print("Mail sent failure: %@", error?.localizedDescription);
            break;
        default:
            break;
        }
        // Close the Mail Interface
        controller.dismiss(animated: true)
    }
Josh
  • 5,781
  • 1
  • 39
  • 67
4

The correct answer is to set the controller's messageComposeDelegate, and to define the following delegate method:

- (void)messageComposeViewController:(MFMessageComposeViewCont‌​roller *)controller
                 didFinishWithResult:(MessageComposeResult)result {

  [self dismissModalViewControllerAnimated:YES];
  if (result == MessageComposeResultCancelled)
    NSLog(@"Message cancelled");
  else if (result == MessageComposeResultSent)
    NSLog(@"Message sent");
  else
    NSLog(@"Message failed");
}

@Doro's answer is based on the MFMailComposeViewController not the MFMessageComposeViewController

BananaNeil
  • 8,263
  • 6
  • 37
  • 53
4

If anyone needs it, the messageComposeDelegate method translated into Swift (3):

func messageComposeViewController(_ controller: MFMessageComposeViewController, didFinishWith result: MessageComposeResult) {
    controller.dismiss(animated: true)
}
teacup
  • 515
  • 1
  • 6
  • 16
0

Here's the answer for Swift 4, iOS 11

case MFMailComposeResult.cancelled:
            print("Mail cancelled");
            break;
        case MFMailComposeResult.saved:
            print("Mail saved");
            break;
        case MFMailComposeResult.sent:
            print("Mail sent");
            break;
        case MFMailComposeResult.failed:
            print("Mail sent failure: %@", error?.localizedDescription);
            break;
        default:
            break;
        }
Josh
  • 5,781
  • 1
  • 39
  • 67
0

Like the answers say, you need to dismiss in the delegate. My issue was I was setting delegate instead of messageComposeDelegate (or mailComposeDelegate for the e-mail version).

Be sure you're setting the right delegate :)

Sam Soffes
  • 14,138
  • 9
  • 68
  • 78