iOS vs Process::openEmailWithAttachments

Hey there

I was getting started trying to get Process::openEmailWithAttachments working on an iOS test app, and I hit an assertion which is annotated quite rightly as:

#if JUCE_IOS
    //xxx probably need to use MFMailComposeViewController

It’s true, lol. Based on MFMailComposeViewController | Apple Developer Documentation indeed we probably do need to use it :slight_smile:

Has anyone managed to get an iOS app to invoke the View for sending emails with attachments?

Cheers!

Not sure if this will help anyone, but if you’re in a bind and need your iOS app to send emails, this seems to work.

  1. In Projucer create a .cpp file called something like IOSPresentMailComposeViewController.mm
  2. Projucer will append a .cpp, so manually remove that so you left with the .mm file extension only.
  3. Drop this code in:
#import <UIKit/UIKit.h>
#import <MessageUI/MessageUI.h>

/** A delegate to handle MFMailComposeViewController callbacks. */
@interface MailComposeDelegate : NSObject <MFMailComposeViewControllerDelegate>
@end

@implementation MailComposeDelegate
- (void)mailComposeController:(MFMailComposeViewController *)controller
          didFinishWithResult:(MFMailComposeResult)result
                        error:(NSError *)error
{
    [controller dismissViewControllerAnimated:YES completion:nil];
}
@end

/** Global delegate instance to ensure it stays in memory. */
static MailComposeDelegate *sharedMailComposeDelegate = nil;

#ifdef __cplusplus
extern "C" {
#endif

/** Presents an MFMailComposeViewController on the main thread. */
void presentMailComposeViewController()
{
    dispatch_async(dispatch_get_main_queue(), ^{
        if (![MFMailComposeViewController canSendMail])
        {
            NSLog(@"Mail services are not available.");
            return;
        }
        
        if (!sharedMailComposeDelegate)
        {
            sharedMailComposeDelegate = [[MailComposeDelegate alloc] init];
        }
        
        MFMailComposeViewController *mailComposeVC = [[MFMailComposeViewController alloc] init];
        mailComposeVC.mailComposeDelegate = sharedMailComposeDelegate;
        [mailComposeVC setSubject:@"Hello"];
        [mailComposeVC setMessageBody:@"This is a test email." isHTML:NO];
        
        UIWindow *keyWindow = [UIApplication sharedApplication].keyWindow;
        UIViewController *rootVC = keyWindow.rootViewController;
        [rootVC presentViewController:mailComposeVC animated:YES completion:nil];
    });
}

#ifdef __cplusplus
}
#endif
  1. In a .h cpp header place:
extern "C" void presentMailComposeViewController();
  1. In that C++ scope you should now be able to call presentMailComposeViewController(); and have the iOS email UI pop-up prepopulated with some text.

Obviously you may want to handle sending args over etc. but this at least should get you started.

Cheers, Jeff