Sending an e-mail in app? - ios

I am new to xcode, and am wondering how to send email in an app! My code is below, but I keep getting an error for the "self presentModalViewController" line. Is my code completely wrong? Or did I just forget to declare the selector, and how do I declare the selector? Someone please help me
MFMailComposeViewController* controller = [[MFMailComposeViewController alloc] init];
controller.mailComposeDelegate = self;
[controller setSubject:#"My Subject"];
[controller setMessageBody:#"Hello there." isHTML:NO];
if (controller)[self presentModalViewController:controller animated:YES];
}
- (void)mailComposeController:(MFMailComposeViewController*)controller
didFinishWithResult:(MFMailComposeResult)result
error:(NSError*)error;
{
if (result == MFMailComposeResultSent) {
NSLog(#"It's away!");
}
[self dismissModalViewControllerAnimated:YES];
}

please present your mail composer using
[self presentViewController:controller animated:YES];

Related

Mock the MFMailComposeViewController on iOS simulator. Just need to display the composer

I just need to display the email composer on my iOS simulator (No need to send the actual mail).
As soon as I am initializing the MFMailComposeViewController I am getting alert pop - up saying that email account is not set.
This is what I am doing.
MFMailComposeViewController* composeVC = [[MFMailComposeViewController alloc] init];
This line pops up the alert controller.
For simulator email configuration is not available.
Use the below code to send email.
- (void)openEmail
{
if ([MFMailComposeViewController canSendMail])
{
MFMailComposeViewController *mail =
[[MFMailComposeViewController alloc] init];
mail.mailComposeDelegate = self;
[mail setSubject:#"Subject"];
[mail setMessageBody:#"body message" isHTML:NO];
[mail setToRecipients:#[#"email1#example.com",#"email2#example.com"]];
/// if attachment then implement below line
//[mail addAttachmentData:<#(nonnull NSData *)#> mimeType:<#(nonnull NSString *)#> fileName:<#(nonnull NSString *)#>]
[self presentViewController:mail animated:YES completion:NULL];
}
else {
NSLog(#"Please configure your email. Settings->Accounts & Passwords->Add Account");
}
}
- (void)mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(nullable NSError *)error
{
switch (result) {
case MFMailComposeResultSent:
NSLog(#"Sent");
break;
default:
break;
}
}

MFMailComposeViewController not dismiss with Cancel button

I've a class that subclass NSObject with a function do display a MFMailComposeViewController. Here is the code :
MFMailComposeViewController *mailController = [[MFMailComposeViewController alloc] init];
mailController.mailComposeDelegate = self;
[mailController setSubject:#"Sample Subject"];
[mailController setMessageBody:#"Here is some main text in the email!" isHTML:NO];
[mailController setToRecipients:#[self.email]];
UITabBarController *tabbarController = (UITabBarController *)[UIApplication sharedApplication].keyWindow.rootViewController;
UINavigationController *navigationController = tabbarController.selectedViewController;
[navigationController.topViewController presentViewController:mailController animated:YES completion:NULL];
Everything works well with this code. The problem is when I want to dismiss the MFMailComposeViewController. Sometime I get a crash, sometimes it just don't happens nothing. I've implemented the delegate function :
- (void)mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error {
UITabBarController *tabbarController = (UITabBarController *)[UIApplication sharedApplication].keyWindow.rootViewController;
UINavigationController *navigationController = tabbarController.selectedViewController;
[navigationController.topViewController dismissViewControllerAnimated:YES completion:nil];
}
After that I tried to show and dismiss it directlty from a ViewController and everything was working. Even the cancel button.
I don't know why it works in my ViewController Class but not in my subclass of NSObject.
When I get the crash I've seen in the logs :
-[MFMailComposeInternalViewController _notifyCompositionDidFinish]
Try this,
- (void)mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error
{
// Do your work and dismiss after you are done with it.
[controller dismissViewControllerAnimated:YES completion:nil];
}
Hope that helps.
Try this in your singleton class
UIViewController *currentViewController;
- (void)sendEmail:(id) viewController {
currentViewController=(UIViewController*)viewController;
NSString * appVersionString =#"";
NSString *strEmailMessage=#"";
NSString *strEmailSubject=#"";
NSArray *toRecipents =#"";
if ([MFMailComposeViewController canSendMail]) {
MFMailComposeViewController *mc = [[MFMailComposeViewController alloc] init];
mc.mailComposeDelegate =viewController;
[mc setSubject:strEmailSubject];
[mc setMessageBody:strEmailMessage isHTML:NO];
[mc setToRecipients:toRecipents];
[viewController presentViewController:mc animated:YES completion:NULL];
}
else{
UIAlertView *alert=[[UIAlertView alloc] initWithTitle:#"Error" message:#"Please setup email account" delegate:nil cancelButtonTitle:#"cancle" otherButtonTitles:nil];
[alert show];
}
}
set delegate like this
mc.mailComposeDelegate =viewController;
to dissmiss viewController
- (void) mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error
{
switch (result)
{
case MFMailComposeResultCancelled:
break;
case MFMailComposeResultSaved:
break;
case MFMailComposeResultSent:
break;
case MFMailComposeResultFailed:
break;
}
// Close the Mail Interface
[currentViewController dismissViewControllerAnimated:YES completion:NULL];
}
i hope this will work...

MailCompositionService quit unexpectedly ios

I am new to this,
I have this code in my viewController,
- (void)sendMail:(id)sender {
NSArray *to = [NSArray arrayWithObjects:#"rayjada11#gmail.com", nil];
mailComposer = [[MFMailComposeViewController alloc] init];
mailComposer.mailComposeDelegate = self;
[mailComposer setToRecipients:to];
[mailComposer setSubject:#"Test Mail"];
[mailComposer setMessageBody:#"Testing message body" isHTML:NO];
[self presentModalViewController:mailComposer animated:YES];
}
#pragma mark - mail compose delegate
-(void)mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error {
if(result) {
NSLog(#"Result = %d", result);
}
if(error) {
NSLog(#"Error = %#", error);
}
[self dismissModalViewControllerAnimated:YES];
}
But when I click send button in my controller, I am getting error like,
2016-09-05 14:55:24.488 mailDemo[1276:104171]
viewServiceDidTerminateWithError: Error
Domain=_UIViewServiceInterfaceErrorDomain Code=3 "(null)"
UserInfo={Message=Service Connection Interrupted} 2016-09-05
14:55:24.989 mailDemo[1276:104171] Trying to dismiss the presentation
controller while transitioning already.
(<_UIFullscreenPresentationController: 0x7fe35b52d2a0>) 2016-09-05
14:55:24.991 mailDemo[1276:104171] transitionViewForCurrentTransition
is not set, presentation controller was dismissed during the
presentation? (<_UIFullscreenPresentationController: 0x7fe35b52d2a0>)
What is the issue?
There is nothing wrong with your code.MFMailComposeViewController is not work for simulator, Try same code in real device.
simulator doesn't supported method and device doesn't login in mail that this method nothing response.
replace this method ::
- (void)sendMail:(id)sender {
if (![MFMailComposeViewController canSendMail]) {
NSLog(#"Mail services are not available.");
return;
}
else{
NSArray *to = [NSArray arrayWithObjects:#"rayjada11#gmail.com", nil];
mailComposer = [[MFMailComposeViewController alloc] init];
mailComposer.mailComposeDelegate = self;
[mailComposer setToRecipients:to];
[mailComposer setSubject:#"Test Mail"];
[mailComposer setMessageBody:#"Testing message body" isHTML:NO];
[self presentModalViewController:mailComposer animated:YES];
}
}
MFMailComposeViewController does not work for simulators. If you try the same code in real device, it will work. There is nothing wrong with your code.

MFMailComposeViewController Keeps Closing Automatically

This is a really weird issue! I have a button on screen which when pressed launches the MFMailComposeViewController using the following code:
-(IBAction) openComposeEmailScreen:(id) sender {
if([MFMailComposeViewController canSendMail]) {
MFMailComposeViewController *mailComposeViewController = [[MFMailComposeViewController alloc] init];
mailComposeViewController.mailComposeDelegate = self;
[mailComposeViewController setToRecipients:[NSArray arrayWithObject:#"johndoe#gmail.com"]];
[mailComposeViewController setSubject:#"HelloWorld"];
NSLog(#"%#",_pasteBoard.string);
[mailComposeViewController setMessageBody:_pasteBoard.string isHTML:NO];
[self presentViewController:mailComposeViewController animated:YES completion:nil];
}
}
-(void) mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error {
if(error) {
NSLog(#"%#",error.localizedDescription);
}
[self dismissViewControllerAnimated:YES completion:nil];
}
Also, my view controller uses the correct protocol:
ViewController ()<MFMailComposeViewControllerDelegate>
I am running this on the simulator.
MFMailComposeViewController isn't supported in the simulator. You have to run on a device.

how to compose mail when button at index clicked in UIActionSheet?

I am a bit confused on how to display mail composer when I click the email option in UIActionSheet.
Here's my sample code:
-(void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
if(buttonIndex == 0)
{
NSString *emailTitle = #"Test Email";
NSString *messageBody = #"iOS programming is so fun!";
NSArray *toRecipents = [NSArray arrayWithObject:#"support#email.com"];
MFMailComposeViewController *mc = [[MFMailComposeViewController alloc] init];
mc.mailComposeDelegate = self;
[mc setSubject:emailTitle];
[mc setMessageBody:messageBody isHTML:NO];
[mc setToRecipients:toRecipents];
[self presentViewController:mc animated:YES completion:NULL];
}
}
Make sure you add to your .h file and import the MessageUI.framework
Here is exactly what your looking for. I use this often. By the way UIActionSheets are deprecated in iOS 8. Here you go though:
.h
ViewController : UIViewController <MFMailComposeViewControllerDelegate>
.m
- (IBAction)showActionSheet:(id)sender {
UIActionSheet *moreActions = [[UIActionSheet alloc] initWithTitle:nil delegate:self cancelButtonTitle:#"Cancel" destructiveButtonTitle:nil otherButtonTitles:#"Add To Favorites", #"Search",#"Email", nil];
[moreActions showInView:self.view];
}
-(void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
switch (buttonIndex) {
case 0: [self addToFav:self];
break;
case 1: ; [self popSearchBar:self];
break;
case 2: { [self sendEmail];
break;
}
break;
}
}
- (void)sendEmail {
NSString *emailTitle = #"This is email title";
// Email Content as for HTML
NSString *messageBody = [NSString stringWithFormat:#"I may have found a missing document in your catalog. I tried opening :<p><strong><font color=\"red\"> %# </font><br>'%#'</strong></p> with no results. Can I have a dollar for reporting this?", self.title, self.titleString];
// To address
NSArray *toRecipents = [NSArray arrayWithObject:#"youremail#google.com"];
MFMailComposeViewController *mc = [[MFMailComposeViewController alloc] init];
mc.mailComposeDelegate = self;
[mc setSubject:emailTitle];
[mc setMessageBody:messageBody isHTML:YES];
[mc setToRecipients:toRecipents];
// Present mail view controller on screen
[self presentViewController:mc animated:YES completion:NULL];
}
- (void) mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult: (MFMailComposeResult)result error:(NSError *)error
{
switch (result)
{
case MFMailComposeResultCancelled:
NSLog(#"Mail cancelled");
[self dismissViewControllerAnimated:YES completion:NULL];
break;
case MFMailComposeResultSaved:
NSLog(#"Mail saved");
[self dismissViewControllerAnimated:YES completion:NULL];
break;
case MFMailComposeResultSent:
NSLog(#"Mail sent");
[self dismissViewControllerAnimated:YES completion:NULL];
break;
case MFMailComposeResultFailed:
NSLog(#"Mail sent failure: %#", [error localizedDescription]);
break;
default:
break;
}
// Close the Mail Interface
[self dismissViewControllerAnimated:YES completion:NULL];
}
Also note that some people are having issues with simulator emails. try it on a device before you give up.
Here's the code:
First add and import the message framework:
#import <MessageUI/MessageUI.h>
then mark your self as a delegate like this
#interface MYViewController () <MFMailComposeViewControllerDelegate>
then to pull up the composer:
- (IBAction)emailButtonPressed:(id)sender
{
if ([MFMailComposeViewController canSendMail]) {
MFMailComposeViewController *composeViewController = [[MFMailComposeViewController alloc] initWithNibName:nil bundle:nil];
[composeViewController setMailComposeDelegate:self];
[composeViewController setToRecipients:#[#"example#email.com"]];
[composeViewController setSubject:#"example subject"];
[self presentViewController:composeViewController animated:YES completion:nil];
}
}
Then to handle the delegate callback and dismiss the composer:
- (void)mailComposeController:(MFMailComposeViewController*)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error
{
//Add an alert in case of failure
[self dismissViewControllerAnimated:YES completion:nil];
}
in actionsheet using actionSheet: clickedButtonAtIndex:
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
//Get the name of the current pressed button
NSString *buttonTitle = [actionSheet buttonTitleAtIndex:buttonIndex];
if ([buttonTitle isEqualToString:#"Your button title"]) {
[self btnContact];
}
}
call this method
- (void)btnContact{
// Email Subject
NSString *emailTitle = #"";
// Email Content
NSString *messageBody = #"";
// To address
NSString *toRecp = #"";
NSArray *toRecipents = [NSArray arrayWithObject:toRecp];
MFMailComposeViewController *mc = [[MFMailComposeViewController alloc] init];
mc.mailComposeDelegate = self;
[mc setSubject:emailTitle];
[mc setMessageBody:messageBody isHTML:NO];
[mc setToRecipients:toRecipents];
// Present mail view controller on screen
[self presentViewController:mc animated:YES completion:NULL];
}
This is appcoda's code . Instead of index use the button's name to fire your mail option .

Resources