MFMailComposeViewController : cancel doesn't exit to my app? - objective-c

I'm trying to send a mail with MFMailComposeViewController. It happens when I click a button on my app. Of course when I click the Cancel button of the mail controller I want to go back to my app view but it doesn't work. What to do ? Here is my code :
MFMailComposeViewController *controller = [[MFMailComposeViewController alloc] init];
controller.mailComposeDelegate = self;
[controller setSubject:#"Subject"];
[controller setMessageBody:#"<html>Test</html>" isHTML:YES];
[controller setToRecipients:nil];
if(controller) [self presentModalViewController:controller animated:YES];
Thanks for your advices

Have you implemented this delegate method? It's called after the composer is exited by the user.
- (void)mailComposeController:(MFMailComposeViewController*)controller
didFinishWithResult:(MFMailComposeResult)result
error:(NSError*)error
{
[self dismissViewControllerAnimated:YES completion:nil];
return;
}

Related

MFMessageComposeViewController does not show up send button and message body on ios8

MFMessageComposeViewController does not show up send button and message body on ios8, when tapping on recipient list keyboard comes up and also send button,message body shows up. Below is the code for message functionality :
MFMessageComposeViewController *msgController = [[MFMessageComposeViewController alloc] init] ;
if([MFMessageComposeViewController canSendText])
{
if (msgController)
{
msgController = nil;
msgController = [[MFMessageComposeViewController alloc] init] ;
}
NSString *messageBody =#"helloWorld";
msgController.body = messageBody;
msgController.recipients = numberArray;
msgController.messageComposeDelegate = (id)self;
[self presentViewController:msgController animated:YES completion:^{}];
Thanks in advance.
First of all add MessageUI framework to your app frameworks and then
#import <MessageUI/MessageUI.h>
#interface class()
<MFMailComposeViewControllerDelegate>
{
....
}
#end
Then in your class implementation write
if ([MFMailComposeViewController canSendMail])
{
MFMailComposeViewController *mail = [[MFMailComposeViewController alloc] init];
[mail setMailComposeDelegate:self];
[mail setSubject:#"Subject goes here..."];
[mail setMessageBody:#"Message body goes here..." isHTML:NO];
[self presentViewController:mail animated:YES completion:NULL];
}
and also implement the delegate for MFMailcomposeViewController as like
- (void)mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error {
[controller dismissViewControllerAnimated:YES completion:nil];
}
There should be recipient and some message in the body to enable the "Send" button.
Here is the link for reference:
https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/SystemMessaging_TopicsForIOS/Articles/SendinganSMSMessage.html#//apple_ref/doc/uid/TP40010416-SW1
http://iosdevelopertips.com/core-services/how-to-send-an-sms-progammatically.html
Hope this helps!

ios: Application tried to present a nil modal view controller on target

I am developing an application,the requirement is to open email composer on a button click of UIAlertView.
message which is in message body of email is copied from UITextView. i am using following code snipt:
-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{
if (buttonIndex == 0)
{
// opening message composer
}
else
{
MFMailComposeViewController *picker = [[MFMailComposeViewController alloc] init];
picker.mailComposeDelegate = self;
[picker setSubject:#"Test mail"];
[picker setMessageBody:messageBody.text isHTML:YES];
[self presentViewController:picker animated:YES completion:NULL];
}
}
// mail compose delegate
- (void)mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error
{
[self dismissViewControllerAnimated:YES completion:NULL];
}
but the issue is that i am getting error saying Application tried to present a nil modal view controller on target. how we can open default mail composer in ios 7?
As per Apple, You should check is MFMailComposeViewController are able to send your mail just before sending
if ([MFMailComposeViewController canSendMail]) {
MFMailComposeViewController *picker = [[MFMailComposeViewController alloc] init];
picker.mailComposeDelegate = self;
[picker setSubject:#"Test mail"];
[picker setMessageBody:messageBody.text isHTML:YES];
[self presentViewController:picker animated:YES completion:NULL];
}
Swift:
if MFMailComposeViewController.canSendMail() else {
// Send mail code
}
Ref : Apple Dev url
Swift 4 version
guard MFMailComposeViewController.canSendMail() else {
print("Mail services are not available")
return
}
sendEmail()
Forgetting Mail account configuration in device settings may also lead to this error. Re check whether a mail account is configured in your device or not.

Cancel button does not dismiss ComposeMail window in iOS simulator

My implementation is pretty simple:
In the .h file, I'm implementing MFMailComposeViewControllerDelegate
And in the .m file, I have the following bit of code:
-(void)MailCurrentViewAsAttachment
{
if ( [MFMailComposeViewController canSendMail] ) {
MFMailComposeViewController * mailComposer = [[MFMailComposeViewController alloc] init];
mailComposer.delegate = self;
[mailComposer addAttachmentData:imageData mimeType:#"image/jpeg" fileName:#"attachment.jpg"];
[self presentViewController:mailComposer animated:YES completion:nil];
}
}
-(void)mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error
{
[self dismissViewControllerAnimated:YES completion:nil];
}
The variable imageData above is of the UIImage type, and I know for sure there's nothing wrong with it: the required image shows up properly in the compose mail window.
However clicking the Cancel button does not dismiss the Compose window. What am I missing?
Note: I'm using iOS 6 with the latest version of xcode, and my app is a Universal app.
You are setting the wrong delegate. You want:
mailComposer.mailComposeDelegate = self;
MFMailComposeViewController extends UINavigationController. So setting delegate is for the UINavigationControllerDelegate.

MFMailComposeViewController won't open after picking an email from the contact list

I'm trying to send an email to a contact on the contact list. I am using a ABPeoplePickerNavigationController. Once the user selects a contact's email, the following happens:
- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifier {
if(property == kABPersonEmailProperty){
[self dismissModalViewControllerAnimated:YES];
ABMultiValueRef emails = ABRecordCopyValue(person, property);
int index = ABMultiValueGetIndexForIdentifier(emails, identifier);
NSString *emailValueSelected = (__bridge NSString*)ABMultiValueCopyValueAtIndex(emails, index);
MFMailComposeViewController* controller = [[MFMailComposeViewController alloc] init];
controller.mailComposeDelegate = self;
[controller setSubject:#"the subject"];
[controller setMessageBody:#"Hello there" isHTML:NO];
[controller setToRecipients:[[NSArray alloc] initWithObjects:emailValueSelected, nil]];
if (controller){
[self presentModalViewController:controller animated:YES];
}
return NO;
}
return YES;
}
The emailValueSelected variable has the correct email value, and all the code seems to be executed without any problems (even the body of the if(controller){...} statement).
The issue is that nothing happens, the email controller is never shown. I've tried both with [self presentViewController:controller animated:YES completion:nil] and [self presentModalViewController:controller animated:YES];.
I use the exact same code on another part of my application to send an email and it works correctly, so I'm guessing it has something to do with the people picker.
Are you using a tab bar controller?
Then you should try
[self.tabBarController presentModalViewController:controller animated:YES];
Also you can set a breakpoint and do a po controller to see if the controller is initialized correctly (i.e. it is not nil)
The problem was that the people picker modal being dismissed was colliding with the email modal which was trying to appear. I solved it by making the people picker modal disappear instantly and not animated.
if(property == kABPersonEmailProperty){
[self dismissModalViewControllerAnimated:NO];
//etc...
}
I had success doing:
[peoplePicker presentViewController:picker animated:YES completion:nil];
instead of:
[self presentViewController:picker animated:YES completion:nil];

Objective C: Send email without leaving app

How do I send an email within an app without leaving the app.
This works:
-(void) sendEmailTo:(NSString *)to withSubject:(NSString *)subject withBody:(NSString *)body {
NSString *mailString = [NSString stringWithFormat:#"mailto:?to=%#&subject=%#&body=%#",
[to stringByAddingPercentEscapesUsingEncoding:NSASCIIStringEncoding],
[subject stringByAddingPercentEscapesUsingEncoding:NSASCIIStringEncoding],
[body stringByAddingPercentEscapesUsingEncoding:NSASCIIStringEncoding]];
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:mailString]];
}
but goes to the mail app to send. Is there a way to do this without leaving the app?
Yes. Use the MFMailComposeViewController.
// From within your active view controller
if([MFMailComposeViewController canSendMail]) {
MFMailComposeViewController *mailCont = [[MFMailComposeViewController alloc] init];
mailCont.mailComposeDelegate = self;
[mailCont setSubject:#"yo!"];
[mailCont setToRecipients:[NSArray arrayWithObject:#"joel#stackoverflow.com"]];
[mailCont setMessageBody:#"Don't ever want to give you up" isHTML:NO];
[self presentViewController:mailCont animated:YES completion:nil];
}
// Then implement the delegate method
- (void)mailComposeController:(MFMailComposeViewController*)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error {
[self dismissViewControllerAnimated:YES completion:nil];
}
Add MessageUI framework:
Click on the project
Select "Build Phases"
Expand "Link Binary With Libraries"
Click "+" and type "Message" to find "MessageUI" framework, then add.
In current view controller add import and implement a protocol:
#import <MessageUI/MessageUI.h>
#import <MessageUI/MFMailComposeViewController.h>
#interface MyViewController : UIViewController<MFMailComposeViewControllerDelegate>
Add methods:
-(void)sendEmail {
// From within your active view controller
if([MFMailComposeViewController canSendMail]) {
MFMailComposeViewController *mailCont = [[MFMailComposeViewController alloc] init];
mailCont.mailComposeDelegate = self; // Required to invoke mailComposeController when send
[mailCont setSubject:#"Email subject"];
[mailCont setToRecipients:[NSArray arrayWithObject:#"myFriends#email.com"]];
[mailCont setMessageBody:#"Email message" isHTML:NO];
[self presentViewController:mailCont animated:YES completion:nil];
}
}
- (void)mailComposeController:(MFMailComposeViewController*)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error {
[controller dismissViewControllerAnimated:YES completion:nil];
}
Updated for iOS 6. Please note that this uses ARC and does not use the deprecated modal view presentation:
#import <MessageUI/MessageUI.h>
#import <MessageUI/MFMailComposeViewController.h>
#interface MyViewController : UIViewController<MFMailComposeViewControllerDelegate>
And then the code to present the email screen:
- (IBAction)emailButtonPushed:(id)sender {
if([MFMailComposeViewController canSendMail]) {
MFMailComposeViewController *mailCont = [[MFMailComposeViewController alloc] init];
mailCont.mailComposeDelegate = self;
[mailCont setSubject:#"Your email"];
[mailCont setMessageBody:[#"Your body for this message is " stringByAppendingString:#" this is awesome"] isHTML:NO];
[self presentViewController:mailCont animated:YES completion:nil];
}
}
- (void)mailComposeController:(MFMailComposeViewController*)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error {
//handle any error
[controller dismissViewControllerAnimated:YES completion:nil];
}