How can I send email using MFMailComposeViewController - ios

I am very new to iPhone development.
In my app, I want to send email using MFMailComposeViewController while clicking a button.
How can I achieve this?
I used the code below.
MFMailComposeViewController *controller = [[MFMailComposeViewController alloc] init];
[controller setSubject:#"Email App"];
[controller setMessageBody:#"Sample email app" isHTML:NO];
[self presentModalViewController:controller animated:YES]; // App crash in this line.
[controller release];
It is showing this warning:
'ImportingDocumentAppDelegate' may not respond to '-presentModalViewController:animated:'.
Thanks.....

#Arun presentModalViewController is the method of UIViewController so you cann't call it on app delegate instance. Add a UIViewController's view to your window then call this method on that view controller.

Your error message indicates that you are telling your app delegate to present the view. You need to call this function on a UIViewController.

Related

MFMailComposeViewController wipes rootViewcontroller

Im making sending an email available for the user with this code:
MFMailComposeViewController *vc = [MFMailComposeViewController new];
[vc setSubject:#"Test Subject"];
[vc setMessageBody:#"Test Body" isHTML:NO];
[vc setMailComposeDelegate:self];
[self presentViewController:vc animated:YES completion:nil];
This opens a ViewController with all the stuff you need to sen an email, but it completely wipes everything from the ViewController the user is previously on. It only removes the subviews because the root view is still there because the backgroundColor is still the same.
I have already tried initWithRootViewController: but it crashes.
What is happening?
I found the bug... It wasn't in the code above. It seems the viewWillDissapear: is getting called when presenting the mailVC :/
In there I have code to remove every subview, so yeah, found the problem thanks anyways for those who answered and sorry for the inconvenience.
I'm not sure what you mean by "completely wipes everything". But suposing this is for iPad (and not iPhone), when presenting a view controller it goes full screen by default. If you want to change that, you have to set the modalPresentationStyle of the presented view controller (MFMailComposeViewController in your case)
Your code would look like this:
MFMailComposeViewController *vc = [MFMailComposeViewController new];
[vc setSubject:#"Test Subject"];
[vc setMessageBody:#"Test Body" isHTML:NO];
[vc setMailComposeDelegate:self];
vc.modalPresentationStyle = UIModalPresentationFormSheet; //You can use custom size too
[self presentViewController:vc animated:YES completion:nil];

Call MFMailComposeViewController from a scrollview

I'm new for iPhone development. My app has a scrollview controller to capture user's information on three pages. When the user completes all info and hits the email button, it should send an email, however, it does not now.
Below is my code and header file. My header file does not implement the MFMailComposeViewControllerDelegate because it implements UIScrollViewDelegate. I think my problem has to do with not implementing the MFMailComposeViewControllerDelegate. How should I redesign this?
Header File
#interface DiveEdScrollViewController : UIViewController <UIScrollViewDelegate>
Call to the eMail:
MFMailComposeViewController *mc = [[MFMailComposeViewController alloc] init];
mc.mailComposeDelegate = self;
[mc setSubject:subjectValue];
[mc setMessageBody:emailBody isHTML:NO];
[mc setToRecipients:diveContacts];
self presentViewController:mc animated:YES completion:NULL];
Your view controller sub-class can adopt more than one protocol by separating with commas like this -
#interface DiveEdScrollViewController : UIViewController <UIScrollViewDelegate, MFMailComposeViewControllerDelegate >
In your .m implement the method
- (void)mailComposeController:(MFMailComposeViewController*)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error
As the documentation states:
Your implementation of this method should dismiss the mail composition view. Implementation of this method is optional but expected.
Also you should check with the following class method first before attempting to show the mail composer like this (to determine whether the device is configured for sending mail or not) -
if ([MFMailComposeViewController canSendMail]) {
[self presentViewController:mc animated:YES completion:NULL];
}

Why UIActivityViewController doesn't dismiss MFMailComposeViewController when the presenter is a UITabbarController child?

I have a very simple case where a button shows an UIActivityViewController to share some content. The problem is that the mail composer is not dismissed when the user cancel or sends email.
NSArray *items = [NSArray arrayWithObjects:#"share",nil];
UIActivityViewController *activityViewController = [[UIActivityViewController alloc] initWithActivityItems:items applicationActivities:nil];
[self presentViewController:activityViewController animated:YES completion:nil];
I tried to dismiss the modal view in the activityViewController.completionHandler but then the console says that another animation is in process and sometimes crash the app, so this isn't the solution. Besides other social networks work well (facebook, twitter) without doing anything.
After some tests I detected that this only occurs if the UIViewController that presents the UIActivityViewController is a child of a UITabBarController.
If in my AppDelegate I create the app like this it doesn't work:
UIViewController > UINavigationController > UITabbarController > Window
but if I remove the tabbar all works fine!:
UIViewController > UINavigationController > Window
A workaround that solves the problem is presenting from the rootviewcontroller.
[self.view.window.rootViewController presentViewController:activityViewController animated:YES completion:NULL];
but I want to know what's happening here.
Thanks! ;)
I had the same issue and after figuring out I get to know that when we don't present mail composer from the class which is currently active on window , it will fail to take responses some time like it will not get even present on every call, same is the problem with dismisal.
It is not that it is only the case with UITabbarController. It can happen to any architecture when you are presenting it from different controller which is not currently on window. That is why your workaround is working and its not wrong though.
I was presenting mail composer from a button tapped inside uipopover. Mail composer was being presented in that popover controller class. And I was facing the same issue you are facing. Then I changed my code to :
MFMailComposeViewController *mailComposer = [MFMailComposeViewController new];
[mailComposer addAttachmentData:data mimeType:#"application/pdf" fileName:model.documentTitle];
[mailComposer setSubject:model.documentTitle]; // Use the document file name for the subject
if(kBccEmailID)
[mailComposer setBccRecipients:[[NSArray alloc]initWithObjects:kBccEmailID, nil ]];
mailComposer.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
mailComposer.modalPresentationStyle = UIModalPresentationFormSheet;
AppDelegate *delagate =(AppDelegate *) [[UIApplication sharedApplication]delegate];
mailComposer.mailComposeDelegate = [[(UINavigationController *)delagate.window.rootViewController viewControllers] lastObject]; // Set the delegate
[(UIViewController *)[[(UINavigationController *)delagate.window.rootViewController viewControllers] lastObject] presentViewController:mailComposer animated:YES completion:nil];
[(UIViewController *)[[(UINavigationController *)delagate.window.rootViewController viewControllers] lastObject] is an alternative for your 'self.view.window.rootViewController'.

Modal View's toolbar is obscured. MFMailComposeViewController

I am trying to bring up an Email Window in my application, however the top toolbar that is suppose to have Cancel and Send is being obscured by the navigation controller.
I believe the reason is that I am calling
if ([MFMailComposeViewController canSendMail]) {
MFMailComposeViewController* controller = [[MFMailComposeViewController alloc] init];
controller.mailComposeDelegate = self;
[controller setToRecipients:[NSArray arrayWithObject:#"internalapps#microstrategy.com"]];
[controller setSubject:#"Mobile HelpDesk App"];
[controller setMessageBody:#"" isHTML:NO];
if (controller){
[self presentViewController:controller animated:YES completion:^{}];
}
}
From a child ViewController that controls a view inside a scrollview (For Paging).
How do I get the toolbar to be on top of the navigation bar? Right now, it's only showing the new email window, but I cannot cancel or send the email.
I tried using [self.parentViewController presentViewController:controller animated:YES completion:^{}];, but that didn't do anything.
Thanks!
You can't use presentViewController:... from a view controller whose view isn't at the top of the view hierarchy (and so most likely doesn't occupy the whole screen). As you've seen, this results in a presented view which is perhaps partially visible and perhaps doesn't respond to touches in some areas.
Trying self.parentViewController is the correct solution (though the code you show is invalid). You need to ensure that you navigate far enough up the hierarchy to get to the 'root' view controller and present from there.
This sounds like it could be as simple as changing:
[self presentViewController:controller animated:YES completion:^{}];
to
[self.navigationController presentViewController:controller animated:YES completion:^{}];
Hope this helps you.

MFmailComposer error

I want to apologize in advance because I am fairly new to programming, so if I am not as specific as I can be I am sorry but I will try to explain my problem as best as I can anyways, I am creating an app that needs to have the ability to send emails and I have looked everywhere, tried every sample code I could find and nothing seems to work every time I use code I get the following error:
2013-02-03 20:23:39.372 Tones[16409:c07] Warning: Attempt to present
on
whose view is not in the window hierarchy!
This is the code I am currently using in the viewcontroller.h file:
UIViewController <MFMailComposeViewControllerDelegate>
- (IBAction)Mail:(id)sender;
and this is in my viewcontroller.m file:
- (IBAction)Mail:(id)sender {
if ([MFMailComposeViewController canSendMail]) {
MFMailComposeViewController *mail = [[MFMailComposeViewController alloc] init];
mail.mailComposeDelegate = self;
[mail setSubject:#"Subject"];
NSArray *recipient = [NSArray arrayWithObjects:#"mail#example.com", nil];
[mail setToRecipients:recipient];
NSString *body = #"body!";
[mail setMessageBody:body isHTML:NO];
[self presentModalViewController:mail animated:YES];
}
}
- (void)mailComposeController:(MFMailComposeViewController*)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error
{
[self dismissModalViewControllerAnimated:YES];
}
I also get a message that says both self presentModalViewController and self dismissModalViewController is deprecated in IOS 6 so does that mean I cant use it or am I doing something wrong?
So any help on what I am doing wrong with the mail composer would be much appreciated and again im sorry if I was not specific enough thanks in advance
You can use presentModalViewController:animated: to show the modal viewcontroller, but it is now recommended to use the new one: presentViewController:animated:completion:. The new on owns a completion handler and you can get more control of the code. Be careful the new method required a iOS 5.0 above. If your target is iOS5.0 above, you should use the new method. And the same for dismissModalViewControllerAnimated:, use dismissViewControllerAnimated:completion: instead.
The warning "Warning: Attempt to present on whose view is not in the window hierarchy!" suggests the view is not connected in the Interface Builder or programmatically.
The Deprecated warnings result from Xcode checking the APIs you use in your project settings. If you set the Build Settings' IOS Deployment Target of your Xcode project to iOS 6, then any APIs (such as presentModalViewController and dismissModalViewController) that are marked by Apple as deprecated will be flagged.
Instead use presentViewController:animated:completion: and dismissViewControllerAnimated:completion:, respectively.
[self presentModalViewController:mail animated:YES];
can be replaced by
[self presentViewController:mail animated:YES completion:nil];
and
[self dismissModalViewControllerAnimated:YES];
by
[self dismissViewControllerAnimated:YES completion:nil];
Like Sudha said, use [self presentViewController:mail animated:YES/NO completion:nil];
From iOS6 onwards, presentModalViewController and dismissModalViewController are deprecated, they are used with completion, which would be nil for your case .
Hi you can check MFMailComposerViewController class present or not.
-(void)email{Class emailClass=(NSClassFromString(#"MFMailComposeViewController"));if emailClass!=nil)if ([emailClass canSendMail]{[self displayComposePage];
}

Resources