MFmailComposer error - ios

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];
}

Related

iOS - Picker controller does not open Photo Library

In my app, i use a UIActionSheet and UIImagePickerController. Action Sheet opens optiones (as choose photo, choose video) and Image Picker Controller opens library. This system works good for iPhone device testing but for iPad, Action Sheet works fine while Picker Controller does not.
I have set required permissions for iOS10, for camera and photo library. This cannot be the problem.
My code for selecting photo:
- (void)selectPhoto {
self.imagePickerController.delegate = self;
self.imagePickerController.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
self.imagePickerController.mediaTypes = [NSArray arrayWithObjects:(NSString *)kUTTypeImage, nil];
[self presentViewController:self.imagePickerController animated:YES completion:nil];
}
Required delegate methods were written either. And as I mentioned, everyting works as it should do in iPhones.
When I try to open photo library first I get this warning messages:
[Warning] <_UIPopoverBackgroundVisualEffectView 0x147c5ad0> is being
asked to animate its opacity. This will cause the effect to appear
broken until opacity returns to 1.
Nothing is broken, app is still running (not freezing). However if I try to open photo library, this time I get:
Warning: Attempt to present on
which is already presenting (null)
Then, the problem might be popover problem but I could not find the answer.
Thank you!
Edit: My action sheet delegate method:
-(void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
[actionSheet dismissWithClickedButtonIndex:buttonIndex animated:YES];
switch (buttonIndex) {
case 0:
[self selectPhoto];
break;
case 1:
[self selectVideo];
break;
default:
break;
}
}
Edit 2: I found that:
On iPad, you must present the browser interface using a popover as
described in initWithContentViewController: and Presenting and
Dismissing the Popover in UIPopoverController Class Reference. If, on
iPad, you attempt to present the browser interface modally
(full-screen), the system raises an exception.
UIPopoverController is now deprecated. Thus I should use another way. If anyone can help me about this, I'd be ver happy.
For iPad use the code to open the UIImagePicker
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
[self presentViewController:picker animated:NO completion:nil];
}];
There is a list of all Cocoa Keys that you can specify in your Info.plist file:
https://developer.apple.com/library/mac/documentation/General/Reference/InfoPlistKeyReference/Articles/CocoaKeys.html
iOS already required permissions to access microphone, camera, and media library earlier (iOS6, iOS7), but since iOS10 the apps will crash if you don't provide the description why you are asking for the permission.
On iPad you can't show UIImagePickerController popover over an already onscreen UIActionSheet popover.
Replace
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
with
- (void)actionSheet:(UIActionSheet *)actionSheet didDismissWithButtonIndex:(NSInteger)buttonIndex;
and it must work.
And remove [actionSheet dismissWithClickedButtonIndex:buttonIndex animated:YES];, as soon as you click on a button, UIActionSheet is dismissed automatically.
To show an image picker on both the iPhone and iPad, you need to present it as a popover.
So the implementation to show your picker would change to
self.imagePickerController.delegate = self;
self.imagePickerController.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
self.imagePickerController.mediaTypes = [NSArray arrayWithObjects:(NSString *)kUTTypeImage, nil];
self.imagePickerController.modalPresentationStyle = UIModalPresentationPopover; //This is needed
self.imagePickerController.sourceView = self.view; //This is needed
[self presentViewController:self.imagePickerController animated:YES completion:nil];
Do make sure your action sheet is dismissed before you present the picker.

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];

iPad Mini crashing on modal segue

I am developing an app that runs on all the deployment target simulators (5.0-6.1) and on my iPhone 3GS, 4, 4S and a gen 2 iPad. I had the opportunity today to try running it on an iPad Mini. I works everywhere except when I try to segue to a MFMailComposeViewController object to send an email, which causes it to crash with an exception.
I use the code directly from the MailComposer sample project, but it always crashes when it calls presentModalViewController:animated:. So I tried presentViewController:animated:completion: as the other method is deprecated, but it still doesn't work.
I linked to MessageUI.framework imported the classes:
#import <MessageUI/MessageUI.h>
#import <MessageUI/MFMailComposeViewController.h>
The delegate is set. Here is the code:
-(void)displayComposerSheet
{
MFMailComposeViewController *picker = [[MFMailComposeViewController alloc] init];
picker.mailComposeDelegate = self;
[picker setSubject:#"Contact Email"];
// Set up recipient
NSArray *toRecipients = [NSArray arrayWithObject:#"info#foo.bar"];
[picker setToRecipients:toRecipients];
// [self presentModalViewController:picker animated:YES];
[self presentViewController:picker animated:YES completion:NULL];
}
Might there be a bug causing this in the iPad Mini? I don't have any other new devices I can try it on so I'm not sure if its a Mini problem or something bigger. Any help would be appreciated as I'm ready to submit to Apple but I sure don't want to do that with a crashing bug.
It's likely that a mail account has not been set up or for some other reason cannot send email.
Be sure to call the + (BOOL)canSendMail function of MFMailComposeViewController first.
Try wrapping your MFMailComposeViewController code with
if ( [MFMailCompseViewController canSendMail])
I'd guess the device doesn't have mail setup on it.

MFMailComposeViewControllerDelegate method does not get called with iOS 6

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

How can I send email using MFMailComposeViewController

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.

Resources