MFMailCompose won't accept input after iOS 18 upgrade

I'm supporting an older iPad app (UIKit and objective C). The ability to send email is a critical part of our app and it's no longer working after upgrading to iOS 18. Every time we create a MFMailComposeViewController, it refuses to accept input from the user. There are multiple UIViewControllers in our code where we create a MFMailComposeViewController for our users to send email from, and the problem consistently affects all of them.

I've upgraded XCode to 16, and written a minimal demo app to try and repro the problem, but haven't been able to repro the problem so far.

When the problem happens, in the XCode console I get a warning, "User interaction with com.apple.MailCompositionService was ignored because it is currently presented in an unsupported configuration. Ensure this view's appearance hasn't been modified."

We're not really doing anything special with it, just the bare basics you would expect when creating a dialog for a user to send an email. No special formatting. But I can't repro the problem In a minimal demo so there's gotta be something different that I'm not accounting for. Any ideas?

Here's the simplest code from our app that triggers the problem:

- (IBAction)sendEmailButtonTapped
{
    NSLog(@"Send Email button tapped");
    if ([MFMailComposeViewController canSendMail] == NO) {
        [[[UIAlertView alloc] initWithTitle:@"Mail Problem" message:@"Can't currently send mail. You may not have any mail accounts set up on this iPad." delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles:nil] show];
        return;
    }

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

    mailComposer.mailComposeDelegate = self;
    {
        NSString * userEmail = [AMPMercuryModel shared].user.userEmail;
        [mailComposer setCcRecipients:@[userEmail]];
    }

    NSArray* mfrEmail = [AMPMercuryModel shared].selectedManufacturer.orderDeskEmails;

    if ([mfrEmail count])
        [mailComposer setToRecipients:mfrEmail];

    [self presentViewController:mailComposer animated:YES completion:nil];
}

- (void)mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error
{
    [controller dismissViewControllerAnimated:YES completion:nil];
    
    NSString* failureMessage;
    
    switch (result) {
        case MFMailComposeResultFailed:
            failureMessage = [NSString stringWithFormat:@"%@\n%@",[error localizedDescription],[error localizedFailureReason]];
            NSLog(@"Email Error: %@",failureMessage);
            [[[UIAlertView alloc] initWithTitle:nil message:failureMessage delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles:nil] show];
            break;
            
        case MFMailComposeResultSent:
        default:
            break;
    }
}

One more bit of information: when I comment out these lines (removing everything I can see that changes the MFMailComposeViewController's appearance at all) our app still has the same problem. So... where else might I look?

[mailComposer setToRecipients:mfrEmail];
[mailComposer setToRecipients:mfrEmail];

Our engineering teams need to investigate this issue, as resolution may involve changes to Apple's software. I'd greatly appreciate it if you could open a bug report, include sample project and sysdiagnose, and post the FB number here once you do. Bug Reporting: How and Why? has tips on creating your bug report.

Rico

WWDR - DTS - Software Engineer

I would have opened a bug report already, except that I can only repo the problem in our main app. Everything works just as it's supposed to in my sample project.

I've confirmed I can repro the problem with our main app on an iPad Pro 12.9in 5th gen (Model MHNF3LL/A), after upgrading it to iOS 18.0. I tried deleting and reinstalling the app, and upgrading to iOS beta 18.1, but the problem remained so I did a refresh, wiped the iPad clean and reinstalled non-beta 18.0 (build 22A3354), but the problem still remains on that iPad.

Since then we've upgraded an older iPad (~10in, 8th gen, model MYL92LL/A) to iOS 18 (build 22A3354) and that seems to work fine with our main app. So it seems like it's somehow tied to either the newer hardware, or the larger-format screen. I believe there is some layout code in the app that treats larger format screens differently, so that's the next thing for me to look at.

I found it! Please let me know if there's a better way to do this. If I don't call this method, it fixes MFMailComposeViewController and the mail dialog accepts input again. Unfortunately, now my main app window only takes up one corner of the screen on a 12.9 inch iPad.

-(void) changeScreenScaling
{
    /*
     Scaling up for iPads that are not 9.7 1024x768.
     See also:
     - https://forums.developer.apple.com/thread/36336
     - https://forums.developer.apple.com/thread/78680
     - https://developer.apple.com/design/human-interface-guidelines/ios/icons-and-images/launch-screen/
     - https://developer.apple.com/ios/submit/

     Note that the resolutions NOT mentioned in the Info.plist UILaunchImageMinimumOSVersion are automatically
     scaled to 9.7" (1024x768) by the iOS. That usually works well, but for example the 11" has different aspect
     ratio so it doesn't really work, an the 2018 12.9" has round corners/safe areas, so that doesn't scale well
     either.

     I'd leave them all to auto-scale anyway, but Apple mandated the proper 12.9" support starting March 2019.
     So. Right now info.plist references 1024x768 and 1366x1024 (12.9" device), that way everything is
     auto-scaled to 9.7", except for the 12.9" that we now handle ourselves (by doing the same scaling further
     down this function).

     The 11" on the other hand is not mandated yet, so we're leaving it out. It's a real pain because a different
     aspect ratio would require change the control layout across the entire app.
     
     As support for more resolutions is added, we be adding them to Info.plist UILaunchImageMinimumOSVersion
     */
    CGSize screenSize = [UIScreen mainScreen].bounds.size;
    CGFloat screenLength = MAX(screenSize.height, screenSize.width);
    CGFloat scale = screenLength / 1024;
    if (scale!=1)
    {
        CGAffineTransform tr = CGAffineTransformMakeScale(scale, scale);
        self.window.transform = tr;
    }
}

I was finally able to repro the problem in a minimal demo app, and have submitted the demo app along with a bug report. The report ID is FB15182286

MFMailCompose won't accept input after iOS 18 upgrade
 
 
Q