MFMailComposeViewControllerDelegate method does not get called with iOS 6 - ios

I present MFMailComposeViewController controller and set it delegate - everything works as expected with iOS 5 but the delegate method (mailComposeController:didFinishWithResult:error:) is not called in iOS6.
Here are code snippets:
MFMailComposeViewController* controller = [[MFMailComposeViewController alloc] init];
controller.mailComposeDelegate = self;
[controller setSubject:<text>];
[controller setMessageBody:<text> isHTML:NO];
[self presentViewController:controller animated:YES completion:nil];
And the following delegate method is not called in iOS6, though the controller is successfully dismissed after Cancel or Done button is pressed:
- (void)mailComposeController:(MFMailComposeViewController*)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error {
if (error != nil) {
NSLog(#"An error occurred while sending e-mail. %#, %#", error, [error userInfo]);
}
NSLog(#"done with e-mail");
[self dismissViewControllerAnimated:YES completion:nil];
}
Any advice will be greatly appreciated! Thank you in advance.
EDIT: Method viewWillAppear: of my controller presenting mailComposeController is not called either! Can it be a clue?

The question was incorrect, as I actually used UIActivityViewController for data sharing in iOS6 and did not create/present MFMailComposeViewController. That is why I did not see the delegate method triggered.

I have an implementation working on iOS6 and got some issues as well, werid as it sounds and dont know if it can help in your case but I changed 2 things from my iOS 5 implementation instead of using
controller.mailComposeDelegate = self;
I used
[controller setMailComposeDelegate:self];
also, I was missing the UINavigationControllerDelegate protocol

Related

Mail and Message not Dismissing from Alert View

I have a UIAlertView that launches an email and a messages screen. When a user clicks on the Alert's button, both views open, however, they do not close.
I have a tried adding:
-(void)mailComposeController:(MFMailComposeViewController*)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error {
[self dismissModalViewControllerAnimated:YES];
}
to the body of the class, however, it did not help.
Here is how the email is presented:
[viewController presentViewController:email animated:YES completion:nil];
Edit Here is the entire code I am using to present the email:
//send email...
-(void)sendEmail{
//mail composer
Class mailClass = (NSClassFromString(#"MFMailComposeViewController"));
if(mailClass != nil){
if([mailClass canSendMail]){
//get the current view controller from the App Delegate
apptester_appDelegate *appDelegate = (apptester_appDelegate *)[[UIApplication sharedApplication] delegate];
UIViewController *viewController = [appDelegate getViewController];
MFMailComposeViewController *email = [[MFMailComposeViewController alloc] init];
email.mailComposeDelegate = self;
//navigation bar color depends on iOS7 or lower...
if(floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_6_1){
[[email navigationBar] setTintColor:[UIColor blackColor];
}else{
[[email navigationBar] setBarTintColor:[UIColor blackColor]];
}
//show the model view...
[viewController presentViewController:email animated:YES completion:nil];
}
}
}
Has anyone else experienced this error?
This may not be relevant, but this app has a tab bar.
Make sure you have set delegate for mail controller
mail.mailComposeDelegate = viewController;
Also try this as well,
[viewController.tabBarController presentViewController:email animated:YES completion:nil];
Have you try this method and pass "controller" instead of self:
-(void)mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error
{
[controller dismissViewControllerAnimated:YES completion:nil];
}
Thanks!
It is the responsibility of presenting controller to dismiss the modal view. Make sure you implement the delegate of the modal in the presenting controller.
Two things:
1) Make sure you set the mailComposeDelegate on the MFMailComposeViewController before you present it.
2) In your mailComposeController:didFinishWithResult:error: method, you should do:
[controller dismissModalViewControllerAnimated:YES];

MFMailComposeViewController Delegate Method Doesn't Get Called

I have a some kind of action sheet UIView which calls MFMailComposeViewController after tapping a button in it, the MFMailComposeViewController gets called and presented successfully, but it doesn't dismiss when the I tap Cancel and sometimes crashes, I know this is a known problem, but I have tried all the known fixes but it doesn't work for me. That's my code:
SendFeedback.h:
#import <UIKit/UIKit.h>
#import <MessageUI/MessageUI.h>
#interface SendFeedback : UIView <UITableViewDelegate, UITableViewDataSource, MFMailComposeViewControllerDelegate, UINavigationControllerDelegate>
//Useless code to the problem.
#property (nonatomic, retain) MFMailComposeViewController *feedBackComposer;
#end
SendFeedback.m:
- (void)baseInit
{
//Useless code to the problem.
feedBackComposer = [[MFMailComposeViewController alloc] init];
[feedBackComposer setMailComposeDelegate:self];
[feedBackComposer setToRecipients:[NSArray arrayWithObject:#"info#getibox.com"]];
[feedBackComposer setMessageBody:#"" isHTML:NO];
[feedBackComposer setSubject:#"What I Love About iBox"];
}
And to call the composer:
- (void)sendFeedbackComposer
{
[self.window.rootViewController presentViewController:feedBackComposer animated:YES completion:nil];
}
To dismiss it:
- (void)mailComposeController:(MFMailComposeViewController *)feedBackComposer didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error
{
//This method doesn't get called.
[self.window.rootViewController dismissViewControllerAnimated:YES completion:nil];
NSLog(#"Error: %#", error);
}
EDIT: So, all the answers provided in this question were correct, and it was all my bad. What I wanted to do is: I had a UINavigationController which includes a UITableView one of the cells in that view should trigger an action sheet which is a UITableView by adding it as a subview, just like the previous one, this view also includes cells and one of them will do an action and it is calling an MFMailComposeViewController, which gets called but doesn't dismiss successfully even though I had its delegate set up and all the methods correct, the cause of the problem was the way of calling the MFMailComposeController, I first removed from super view that little UITableView then presented the MFMailComposeController, so when I dismissed the mail composer it crashed without even giving a result, which made me confuse the cause of the crash with the delegate method, fool me.
Here's the code:
- (void)removeView
{
if (self) {
[UIView animateWithDuration:0.3
animations:^{backgroundView.alpha = 0;}
completion:^(BOOL finished){
[UIView animateWithDuration:.3
animations:^{self.frame = CGRectMake(0, 568, 320, 568);}
completion:^(BOOL finished){[self removeFromSuperview];}];
}];
}
}
- (void)sendFeedbackComposer
{
feedBackComposer = [[MFMailComposeViewController alloc] init];
[feedBackComposer setMailComposeDelegate:self];
[feedBackComposer setToRecipients:[NSArray arrayWithObject:#"info#getibox.com"]];
[feedBackComposer setMessageBody:#"" isHTML:NO];
[feedBackComposer setSubject:#"What I Love About iBox"];
[self.window.rootViewController presentViewController:self.feedBackComposer animated:YES completion:nil];
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
switch (indexPath.row) {
case 2: //That's the index of the MailComposer caller.
[self removeView];
[self sendFeedbackComposer];
break;
case 6:
[self removeView];
break;
default:
break;
}
}
- (void)mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error
{
[feedBackComposer.presentingViewController dismissViewControllerAnimated:YES completion:nil];
NSLog(#"Error: %#", error);
}
Thanks to Stefan Atanasov, Jim, and Vitaly S.
Are you sure that delegate method isn't called? I made a test and it's called, but to dismiss mail composer use such code:
[feedBackComposer dismissViewControllerAnimated: YES completion: nil];
Also it's really strange to implement delegates in view implementation, not in view controller
To add something to Vitaly S.'s answer (due to lack of reputation I can't comment directly on it, sorry) - the delegate method is called, so the problem is the dismissal. You can try this:
[feedBackComposer.presentingViewController dismissViewControllerAnimated: YES completion: nil];
The delegate methods need to be called from the viewController, not from within the UIView.
Your view controller that calls the UIView will have your delegates
<UITableViewDelegate, UITableViewDataSource, MFMailComposeViewControllerDelegate, UINavigationControllerDelegate>
within it's header file.
You need to make a delegate method to pass information from the UIView to the controller, which will in turn call the mail and table delegate methods.
Here is a link to a question that demonstrates how to use a delegate protocol to trigger a method in the view controller from the UIView.
Trigger a method in UIViewController from its View
Hope this helps, Jim
you need to check is it device is configure to send mail by checking MFMailComposeViewController is avail to respond or not.
if([MFMailComposeViewController canSendMail]){
//your code
}

Modal App Store won't dismiss

I have a button that shows my app in a modal view, so that people can download and rate the app. I got it to show up modally with this code.
NSDictionary *appParameters = [NSDictionary dictionaryWithObject:#"607257427"
forKey:SKStoreProductParameterITunesItemIdentifier];
SKStoreProductViewController *productViewController = [[SKStoreProductViewController alloc] init];
[productViewController setDelegate:self];
[productViewController loadProductWithParameters:appParameters
completionBlock:^(BOOL result, NSError *error)
{
}];
[self presentViewController:productViewController
animated:YES
completion:^{
}];
`
This is what it turns into.
Problem is that the cancel button isn't working, it may be something with the Simulator or also something really simple, but I can't figure out why the cancel button isn't working
You need to implement the delegate method to dismiss the view controller:
- (void)productViewControllerDidFinish:(SKStoreProductViewController *)viewController
{
[viewController dismissViewControllerAnimated:YES completion:nil];
}

remove ViewController from parent screen stays black

I'm having trouble with removing a modal view.
I want to show (after pressing a button) a my own SendMailViewController which it self shows a MFMailComposeViewController. Then and after pressing cancel of send, in my own SendMailView controller in didFinishWithResult i do a [self dismissModalViewControllerAnimated:YES] and that works. The MFMailComposeView goes away.
But then the screen stays black....it think i also have to remove my SendMailViewController from it's parent. That's where i pushed the button...even after [self removeFromParentViewController] it still stays black...
Where do i go wrong?
And yes i would like the extra viewcontroller (SendMailViewController) because that controller will become the delegate of MFMailComposeViewController. Otherwise my caller (controller with the button) get's to much responsibility. Or do i also go wrong here?
Thanks,
/jr00n
- (IBAction)tapExportButton:(id)sender
{
SendMailViewController *sendMailController = [[SendMailViewController alloc]init];
[self presentViewController:sendMailController animated:YES completion:^() {[sendMailController openMailDialog];}];
[sendMailController release];
}
SendMailViewController:
- (void)openMailDialog
{
if ([MFMailComposeViewController canSendMail])
{
MFMailComposeViewController *mailer = [[MFMailComposeViewController alloc] init];
mailer.mailComposeDelegate = self;
...
[self presentModalViewController:mailer animated:YES];
}
}
- (void)mailComposeController:(MFMailComposeViewController*)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error
{
....
// Remove the mail view
// first i did this:
// [self dismissModalViewControllerAnimated:YES];
[self dismissViewControllerAnimated:YES completion:^{[self removeFromParentViewController];}];
}
The problem is with the [self dismissViewControllerAnimated:YES completion:^{[self removeFromParentViewController];}]; in your didFinishWithResult method.
Remove that line and add the following line,
[controller dismissViewControllerAnimated:YES completion:^{[self dismissViewControllerAnimated:YES completion:nil]}];
That make sure we dismiss the controller after dismissing the MailController

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