Mfmailcomposeviewcontroller Error [Mc] Filtering Mail Sheet Accounts for Bundle Id

Click alert button to show MFMailComposeViewController

Your code tries to present the mail view controller (and also the error alert) on a new view controller which you create with instantiateViewController. Since this new VC itself is not part of your app's VC hierarchy, neither it nor the mail VC will appear on screen.

To make this work, you can either pass a view controller which is part of your app into your sendmail method:

func sendmail(_ root: UIViewController) {
...
root.present(mailComposeViewController, animated: true, completion: nil)
...

Or you can use a globally accessible VC of your app; in a simple app using the root VC should work:

func sendmail() {
...
let root = UIApplication.shared.keyWindow?.rootViewController
root?.present(mailComposeViewController, animated: true, completion: nil)
...

I'd suggest the first approach because it is more flexible (e.g. it allows you to open your mail screen anywhere, even when your VC hierarchy gets more complex).

Privacy Problems with MFMailComposeViewController and iOS 10 only

So after much analysis I finally figured this problem out last weekend. The key to knowing it actually had nothing to do with MFMailComposeViewController privacy changes in iOS 10 was this log message:

[MC] Result: YES

If you get a "NO" then you have a privacy problem, but a YES indicates that privacy was not an issue. I finally found, in my case here anyway, that the problem was is a timing issue in my code uncovered running in iOS 10.

On the same exact device model being testing, one with iOS 10 and one with iOS 9.3.5 the problem was an error path UIAlertController present request being called when another alert was already presented. On iOS 9.x and earlier it was just "luck" that the expected one won out and got presented first every single time. But on iOS 10 it failed to do so every single time and this then blocked the MFMailComposeViewController in my situation.

The following code was problematic :

[self presentViewController:crashMailAlertController animated:YES completion:nil];

Replacing it with this code resolved the issue:

[self dismissViewControllerAnimated:YES completion:^{
[self presentViewController:crashMailAlertController animated:YES completion:nil];
}];

In my case all I wanted was to insure that this error path UIAlertController was always presented first as it was a rare event (only when a crash had happened), so dismissing any previous alert first was the ticket to getting it up so that the MFMailComposeViewController would follow as it was embedded in the alert button action.

Getting a black screen when clicking the contact button prior to the send button

Please use the code to open mail in swift with an extension like below.

extension SendEmailVC: MFMailComposeViewControllerDelegate {

func contact() {

if !MFMailComposeViewController.canSendMail() {
ROAlert.warningAlertUnderNavigation(ROConstants.More.kNoMailConfigured, onView: self.view)
return ()
}
let composeVC = MFMailComposeViewController()
composeVC.mailComposeDelegate = self
composeVC.setToRecipients([ROConstants.More.kContactEmail])
// Present the view controller modally.
self.present(composeVC, animated: true, completion: nil)
}

//MARK: - MFMailComposeViewControllerDelegate

func mailComposeController(_ controller: MFMailComposeViewController,
didFinishWith result: MFMailComposeResult, error: Error?) {
// Check the result or perform other tasks.

// Dismiss the mail compose view controller.
controller.dismiss(animated: true, completion: nil)
}

}

Getting a black screen when clicking the contact button prior to the send button

Please use the code to open mail in swift with an extension like below.

extension SendEmailVC: MFMailComposeViewControllerDelegate {

func contact() {

if !MFMailComposeViewController.canSendMail() {
ROAlert.warningAlertUnderNavigation(ROConstants.More.kNoMailConfigured, onView: self.view)
return ()
}
let composeVC = MFMailComposeViewController()
composeVC.mailComposeDelegate = self
composeVC.setToRecipients([ROConstants.More.kContactEmail])
// Present the view controller modally.
self.present(composeVC, animated: true, completion: nil)
}

//MARK: - MFMailComposeViewControllerDelegate

func mailComposeController(_ controller: MFMailComposeViewController,
didFinishWith result: MFMailComposeResult, error: Error?) {
// Check the result or perform other tasks.

// Dismiss the mail compose view controller.
controller.dismiss(animated: true, completion: nil)
}

}

How to add a UIImage in MailComposer Sheet of MFMailComposeViewController

Back again with a new answer. I'm still leaving my previous code up though, because I'm still not convinced that there's not a way to make use of it. I'll keep at it myself. The following code DOES work. Mustafa suggests base64 encoding the images, and says that they only work Apple to Apple, but that's not actually true. Base64 encoding does work with most mail clients now (IE previously didn't support it, but now it is supported for images up to a certain size, though I'm not sure exactly what the size is). The problem is that mail clients like Gmail would strip out your image data, but there's a simple workaround for that... just putting <b> and </b> tags around your <img ...> tag is all you need to do to keep it from getting stripped out. In order to get an image into your email, you need to get a base64 encoder into your project. There are several out there (mostly C though), but the simplest ObjC one I found was called NSData+Base64 by Matt Gallagher (I took the "+" out of the name after copying it in because it gave me problems). Copy the .h and .m files into your project and be sure to #import the .h file where you plan on using it. Then code like this will get an image into your email body...

- (void)createEmail {
//Create a string with HTML formatting for the email body
NSMutableString *emailBody = [[[NSMutableString alloc] initWithString:@"<html><body>"] retain];
//Add some text to it however you want
[emailBody appendString:@"<p>Some email body text can go here</p>"];
//Pick an image to insert
//This example would come from the main bundle, but your source can be elsewhere
UIImage *emailImage = [UIImage imageNamed:@"myImageName.png"];
//Convert the image into data
NSData *imageData = [NSData dataWithData:UIImagePNGRepresentation(emailImage)];
//Create a base64 string representation of the data using NSData+Base64
NSString *base64String = [imageData base64EncodedString];
//Add the encoded string to the emailBody string
//Don't forget the "<b>" tags are required, the "<p>" tags are optional
[emailBody appendString:[NSString stringWithFormat:@"<p><b><img src='data:image/png;base64,%@'></b></p>",base64String]];
//You could repeat here with more text or images, otherwise
//close the HTML formatting
[emailBody appendString:@"</body></html>"];
NSLog(@"%@",emailBody);

//Create the mail composer window
MFMailComposeViewController *emailDialog = [[MFMailComposeViewController alloc] init];
emailDialog.mailComposeDelegate = self;
[emailDialog setSubject:@"My Inline Image Document"];
[emailDialog setMessageBody:emailBody isHTML:YES];

[self presentModalViewController:emailDialog animated:YES];
[emailDialog release];
[emailBody release];
}

I've tested this on the iPhone and sent lovely image embedded emails to myself on Yahoo, my personal website, and my MobileMe. I don't have a Gmail account, but the Yahoo worked perfectly, and every source I've found says that the bold-tags are all you need to make it work. Hope this helps all!



Related Topics



Leave a reply



Submit