Search code examples
iosobjective-cuinavigationcontrollermfmessagecomposeviewcontroller

MFMessageComposeVIewController is dismissing its delegate instead of itself


I have a VC that conforms to the MFMessageComposeViewControllerDelegate protocol.

I am successfully presenting this view controller with the following code:

- (IBAction)textAction:(id)sender {
    if(![MFMessageComposeViewController canSendText])
    {
        UIAlertView *warningAlert = [[UIAlertView alloc] initWithTitle:@"Error" message:@"Your device doesn't support SMS!" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
        [warningAlert show];
        return;
    }

    NSString *numberToCallOrText = self.phoneNumber;
    NSString *message = @"Test message";
    NSArray *recipients = [NSArray arrayWithObject:numberToCallOrText];
    MFMessageComposeViewController *messageController = [[MFMessageComposeViewController alloc] init];
    messageController.messageComposeDelegate = self;
    [messageController setRecipients:recipients];
    [messageController setBody:message];

    // Present message view controller on screen
    [self.view endEditing:YES];
    [self presentViewController:messageController animated:YES completion:nil];
}

Additionally, I am handling the finish result like so:

- (void)messageComposeViewController:(MFMessageComposeViewController *)controller didFinishWithResult:(MessageComposeResult) result
{
    switch (result) {
        case MessageComposeResultCancelled:
            NSLog(@"Canceled");
            break;

        case MessageComposeResultFailed:
        {
            NSLog(@"Failed");
            UIAlertView *warningAlert = [[UIAlertView alloc] initWithTitle:@"Error" message:@"Failed to send SMS!" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
            [warningAlert show];
            break;
        }

        case MessageComposeResultSent:
            NSLog(@"sent");
            [self.navigationController popViewControllerAnimated:YES];
            break;

        default:
            break;
    }
    [controller.view endEditing:YES];
    [self.navigationController popViewControllerAnimated:YES];
//    [self dismissViewControllerAnimated:YES completion:nil];
//    [controller popToViewController:self animated:YES];
//    [controller dismissViewControllerAnimated:YES completion:nil];
}

The three commented out lines are alternatives that I have tried. What's happening is that the MFMessageComposeViewController is remaining on the screen (though the keyboard is dismissed), but the delegate is being popped from the stack. Therefore, when I hit cancel again, I get a null reference error.

It's odd, because this same implementation works elsewhere in my code. The only difference is that I've set the body to be initialized.

Any ideas why the wrong VC is getting popped here?

Thanks.

Edit - The broken implementation is on a UITableViewController rather than UIView Controller... could that be what is causing the problem?


Solution

  • The issue appears to stem from calling MFMessageComposeViewController from a UITableViewController instead of a UIViewController. Therefore, my solution was to instead have the table push another view controller whose sole purpose is pushing the MFMessageComposeViewController, and dismissing itself in the completion handler for the MFMessageComposeViewController.