Trying to send an email through an iphone app and getting an error using MFMailComposeViewController in iOS 8
This is a known error in the simulator. It does not appear when you run on a device. So, try it on a device and if it runs normally, then you should be ok.
I have REAL misunderstanding with MFMailComposeViewController in Swift (iOS8) in Simulator
* * IMPORTANT - DO NOT USE THE SIMULATOR FOR THIS. * *
Even in 2016, the simulators very simply do not support sending mail from apps.
Indeed, the simulators simply do not have mail clients.
But! Do see the message at the bottom!
Henri has given the total answer. You MUST
-- allocate and initiate MFMailComposeViewController in an earlier stage, and
-- hold it in one static variable, and then,
-- whenever it's needed, get the static MFMailComposeViewController instance and use that.
AND you will almost certainly have to cycle the global MFMailComposeViewController after each use. It is not reliable to re-use the same one.
Have a global routine which releases and then re-initializes the singleton MFMailComposeViewController
. Call to that global routine, each time, after you are finished with the mail composer.
Do it in any singleton. Don't forget that your app delegate is, of course, a singleton, so do it there...
@property (nonatomic, strong) MFMailComposeViewController *globalMailComposer;
-(BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
........
// part 3, our own setup
[self cycleTheGlobalMailComposer];
// needed due to the worst programming in the history of Apple
.........
}
and...
-(void)cycleTheGlobalMailComposer
{
// cycling GlobalMailComposer due to idiotic iOS issue
self.globalMailComposer = nil;
self.globalMailComposer = [[MFMailComposeViewController alloc] init];
}
Then to use the mail, something like this ...
-(void)helpEmail
{
// APP.globalMailComposer IS READY TO USE from app launch.
// recycle it AFTER OUR USE.
if ( [MFMailComposeViewController canSendMail] )
{
[APP.globalMailComposer setToRecipients:
[NSArray arrayWithObjects: emailAddressNSString, nil] ];
[APP.globalMailComposer setSubject:subject];
[APP.globalMailComposer setMessageBody:msg isHTML:NO];
APP.globalMailComposer.mailComposeDelegate = self;
[self presentViewController:APP.globalMailComposer
animated:YES completion:nil];
}
else
{
[UIAlertView ok:@"Unable to mail. No email on this device?"];
[APP cycleTheGlobalMailComposer];
}
}
-(void)mailComposeController:(MFMailComposeViewController *)controller
didFinishWithResult:(MFMailComposeResult)result
error:(NSError *)error
{
[controller dismissViewControllerAnimated:YES completion:^
{ [APP cycleTheGlobalMailComposer]; }
];
}
{nb, fixed typo per Michael Salamone below.}
Have the following macro in your Prefix file for convenience
#define APP ((AppDelegate *)[[UIApplication sharedApplication] delegate])
Also here's a "minor" problem which can cost you days: https://stackoverflow.com/a/17120065/294884
Just for 2016 FTR here's the basic swift code to send an email IN APP,
class YourClass:UIViewController, MFMailComposeViewControllerDelegate
{
func clickedMetrieArrow()
{
print("click arrow! v1")
let e = MFMailComposeViewController()
e.mailComposeDelegate = self
e.setToRecipients( ["help@smhk.com"] )
e.setSubject("Blah subject")
e.setMessageBody("Blah text", isHTML: false)
presentViewController(e, animated: true, completion: nil)
}
func mailComposeController(controller: MFMailComposeViewController, didFinishWithResult result: MFMailComposeResult, error: NSError?)
{
dismissViewControllerAnimated(true, completion: nil)
}
However! Note!
These days it is crappy to send an email "in app".
It's much better today to simply cut away to the email client.
Add to plist ...
<key>LSApplicationQueriesSchemes</key>
<array>
<string>instagram</string>
</array>
and then code like
func pointlessMarketingEmailForClient()
{
let subject = "Some subject"
let body = "Plenty of <i>email</i> body."
let coded = "mailto:blah@blah.com?subject=\(subject)&body=\(body)".stringByAddingPercentEncodingWithAllowedCharacters(.URLQueryAllowedCharacterSet())
if let emailURL:NSURL = NSURL(string: coded!)
{
if UIApplication.sharedApplication().canOpenURL(emailURL)
{
UIApplication.sharedApplication().openURL(emailURL)
}
else
{
print("fail A")
}
}
else
{
print("fail B")
}
}
These days, that is much better than trying to email from "inside" the app.
Remember again the iOS simulators simply do not have email clients (nor can you send email using the composer within an app). You must test on a device.
Xcode 6 MFMailComposeViewController does NOT work
Look at this topic: MFMailComposeViewController dismisses right away
The response from Max seems to deal with this problem. It´s not the mail address or the mail account.
Xcode 8 SiriKit Extension - Could not attach to pid
Fixed the problem after weeks of debugging.
My problem was that SiriKit was running on armv7 architecture. Changing it to arm64 or the default setting of armv7 + arm64 will fix this problem.
I hope this helps someone!
Related Topics
Core Data: Delete All Objects of an Entity Type, Ie Clear a Table
How to Install the "App Store" in an iOS Simulator
What the Meaning of Question Mark '' in Swift
How to Import Existing Objective C Classes in Swift
Uitableviewcell Selected Background Color on Multiple Selection
How to Use Mbprogresshud with Swift
Leaving Inputaccessoryview Visible After Keyboard Is Dismissed
Where to Highlight Uicollectionviewcell: Delegate or Cell
Swift: Save Video from Nsurl to User Camera Roll
Add a View on Top of the Keyboard Using Inputaccessoryview
How to Disable Custom Keyboards (Ios8) for My App
Sfspeechrecognizer - Detect End of Utterance
Change Uifont in Secure Uitextfield Strange Behaviour in iOS7
What Is Correct Format of Bundle Identifier in iOS
How to Test for the Class of a Variable in Swift
How to Increase Width of Textfield According to Typed Text
Why Are Animations on Bounds of an Uilabel Only Working When Increasing the Size
Coredata Asynchronous Fetch Causes Concurrency Debugger Error