ObjectiveC MessageComposerViewController on iPhone device. All is ok with iPad - objective-c

I've got a problem with my universal app. In particular my problem is about using MessageComposerViewController (MCVC). I want to send email with a pdf attached and all works done. My problem occurs when I dismiss the MessageComposerViewController. Indeed when I remove MCVC from main view I'd like that subviews in mainView continue to has exclusiveTouch tag flagged to true.
This behavior occurs when I run my app on iPad but it doesn't happen when I use iPhone. When I use iPhone device, after I've sent an e-mail (or after I've aborted it) the touch signal is captured by mainview and I don't know the reason.
My hierarchy is:
mainView (GameView) within some subviews that I use to manage file actions: (open file, send file, remove file). To apply the right actions I've linked a UITapGestureRecognizer to the 3 buttons. After MCVC is dismissed, I'd like to continue using the three buttons but I can't.
I post some code:
MCMessageComposerViewController.h:
#interface MessageComposerViewController : UIViewController{
MFMailComposeViewController *mc;}
MCMessageViewController.m:
- (void)mailComposeController:(MFMailComposeViewController*)controller
didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error{
self.feedbackMsg.hidden = NO;
// Notifies users about errors associated with the interface
switch (result)
{
case MFMailComposeResultCancelled:
self.feedbackMsg.text = #"Result: Mail sending canceled";
break;
case MFMailComposeResultSaved:
self.feedbackMsg.text = #"Result: Mail saved";
break;
case MFMailComposeResultSent:
self.feedbackMsg.text = #"Result: Mail sent";
break;
case MFMailComposeResultFailed:
self.feedbackMsg.text = #"Result: Mail sending failed";
break;
default:
self.feedbackMsg.text = #"Result: Mail not sent";
break;
}
[mc.navigationController popViewControllerAnimated:YES];
[mc dismissViewControllerAnimated:YES completion:nil];
[self.view removeFromSuperview];
}
- (void)displayMailComposerSheet:(NSString *)_fileName{
NSString *pathFile = #"blablablaPath";
NSString *emailTitle = "blablablaTitle";
mc = [[MFMailComposeViewController alloc] init];
mc.mailComposeDelegate = self;
[mc setSubject:emailTitle];
// Get the resource path and read the file using NSData
NSData *fileData;
while(!fileData){
fileData = [NSData dataWithContentsOfFile:pathFile];
if(fileData) break;
[f_t createPdfWithName:_fileName];}//create pdf file if it isn't exist
[mc addAttachmentData:fileData mimeType:#"application/pdf" fileName:_fileName];
[self presentViewController:mc animated:YES completion:NULL];}
GameView.m:
- (void)sendFile:(UITapGestureRecognizer *)recognizer{
mail = [[MessageComposerViewController alloc] init];
[self addSubview:mail.view];
[mail displayMailComposerSheet: fileName];
}
I'd like to post an image but I've not enough reputation to do this...
Please help me!!! :-)

Related

unable to send the mail using objective c?

i am very new to objective c.i am trying to send the email whenever the user clicks the send button.whenever i clicks the button the if condition is not satisfied and coming out of the loop also the email is not send.
This is my .h file
#import <UIKit/UIKit.h>
#import <MessageUI/MessageUI.h>
#interface complaintsviewcontroller : UITableViewController<MFMailComposeViewControllerDelegate>
This is my .m file
- (IBAction)sendbutton:(id)sender {
if ([MFMailComposeViewController canSendMail])
{
NSString *emailTitle = #"Test Email";
// Email Content
NSString *messageBody = #"testing ";
// To address
NSArray *toRecipents = [NSArray arrayWithObject:#"noreply#etowns.in"];
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];
}
}
-(void)mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error {
switch (result)
{
case MFMailComposeResultCancelled:
NSLog(#"Mail cancelled");
break;
case MFMailComposeResultSaved:
NSLog(#"Mail saved");
break;
case MFMailComposeResultSent:
NSLog(#"Mail sent");
break;
case MFMailComposeResultFailed:
NSLog(#"Mail sent failure: %#", [error localizedDescription]);
break;
default:
break;
}
[self dismissViewControllerAnimated:YES completion:NULL];
}
can anyone suggest me what is the mistake i done in the above coding ?
As per the standards you need to check MFMailComposeViewController is able to send your mail just before sending using below condition.
if ([MFMailComposeViewController canSendMail]){
// configure your email part here
// if not checking, this misleads the standards or leads uncertainty further
}
After that if you have not configured mail Mail Accounts under the settings -> mail, an alert appears like below.
Final Solution: If you got something like above popup just configure the mail account with gmail, yahoo or anyone, so the mailcomposer will be able to send email on behalf.

how to attach to an email a PDF file in Xcode5

I'm developing an app for Ipad (iOS7.1) in Xcode5 which opens an e-mail modal viewcontroller for sending email by using MFMailComposeViewController
I want to attach a PDF archive to my email
this is my code:
Functions.m:
#import <MessageUI/MessageUI.h>
#interface Functions()<MFMailComposeViewControllerDelegate>
#end
#implementation Functions
-(void)sendEmailInViewController:(UIViewController *)viewController {
NSString *emailTitle = #"Hello";
NSArray *toRecipents = [[NSArray alloc]initWithObjects:#"jesus#mymail.com", nil];
NSMutableString *messageBody =[[NSMutableString alloc]init];
[messageBody appendString:#"<p> </p><p> </p><p> </p><p><span style=\"font-size:14px;\"><span style=\"color: rgb(0, 0, 102);\"><span style=\"font-family: arial,helvetica,sans-serif;\"><strong>Jesus</strong><br />Gerente Select / Sucursal Santa Fe<br />Paseo de la Lidia No. 801 Piso 8 Mod. 162<br />Col. Lomas del Pedregal, C.P. 01292, México D.F.<br />Tel: + (55) 8728-0908. Ext. 12832<br />e-mail: jesus#mymail.com</span></span></span></p><p><span style=\"color:#000066;\"><span style=\"font-family: arial,helvetica,sans-serif;\"></span></span></p>"];
Class mailClass = (NSClassFromString(#"MFMailComposeViewController"));
if (mailClass != nil) {
MFMailComposeViewController * mailView = [[MFMailComposeViewController alloc] init];
mailView.mailComposeDelegate = self;
//Set the subject
[mailView setSubject:emailTitle];
//Set the mail body
[mailView setMessageBody:messageBody isHTML:YES];
[mailView setToRecipients:toRecipents];
NSData *pdfData = [NSData dataWithContentsOfFile:#"google.pdf"];
[mailView addAttachmentData:pdfData mimeType:#"application/pdf" fileName:#"google.pdf"];
//Display Email Composer
if([mailClass canSendMail]) {
[viewController presentViewController:mailView animated:YES completion:NULL];
}
}
}
- (void) mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error{
switch (result){
case MFMailComposeResultCancelled:NSLog(#"Mail cancelled"); break;
case MFMailComposeResultSaved: NSLog(#"Mail saved"); break;
case MFMailComposeResultSent: NSLog(#"Mail sent"); break;
case MFMailComposeResultFailed: NSLog(#"Mail sent failure: %#", [error localizedDescription]); break;
default: break;
}
// Close the Mail Interface
if (!app) { app = (AppDelegate *)[[UIApplication sharedApplication] delegate]; }
if (!currentSplitViewController) {
currentSplitViewController = (UISplitViewController *) app.window.rootViewController;
}
navController = [currentSplitViewController.viewControllers lastObject];
[[navController topViewController] dismissViewControllerAnimated:YES completion:NULL];
}
#end
on any viewController I call to my method this way:
- (IBAction)showEmail:(id)sender {
[functions sendEmailInViewController:self];
}
this is the screenshot of my mail:
it shows a logo of my pdf file, but when my message is sent, I open my inbox but I just find the signature, but anything attached for viewing... how to attach and send it correctly???
any help I'll appreciate
EDIT: this is the answer: I just had to add this
NSData *pdfData = [NSData dataWithContentsOfFile:[[NSBundle mainBundle]pathForResource:#"google" ofType:#"pdf"]];
[mailView addAttachmentData:pdfData mimeType:#"application/pdf" fileName:#"google"];
this is my result:
Sounds like you need to look at the "addAttachmentData:mimeType:fileName:" method of MFMailComposeViewController.
And using that method, you'll be able to add the raw NSData for whatever archive you want to send along. Just make certain you set the appropriate mime type (e.g. "application/zip") and file name (e.g. "MyArchive.zip").
For PDF files, the mime type would be "application/pdf" and you would use a filename like "google.pdf". Then all you would need to do is load a NSData object with the file data you want to attach.

Trouble sending email in iOS 7 using MFMailComposeViewController

I have a very simple app to test sending email, but the email never arrives. I have included the MessageUI framework in the app, and implemented the MFMailComposeViewControllerDelegate as well. The two methods in the app are as follows:
- (IBAction)showEmail:(id)sender
{
// Email Subject
NSString *emailTitle = #"Test Email";
// Email Content
NSString *messageBody = #"iOS programming is so fun!";
// To address
NSArray *toRecipents = [NSArray arrayWithObject:#"email#address.com"];
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];
}
and the delegate method:
- (void) mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error
{
switch (result)
{
case MFMailComposeResultCancelled:
NSLog(#"Mail cancelled");
break;
case MFMailComposeResultSaved:
NSLog(#"Mail saved");
break;
case MFMailComposeResultSent:
NSLog(#"Mail sent");
break;
case MFMailComposeResultFailed:
NSLog(#"Mail sent failure: %#", [error localizedDescription]);
break;
default:
break;
}
// Close the Mail Interface
[self dismissViewControllerAnimated:YES completion:NULL];
}
When I press the email button in my app the first method works perfectly and when I click the send button that is presented, the "Mail Sent" message appears in the log. The email simply never arrives.
Everything seems to work as advertised, with the exception of the email never arriving at its destination.
I am running this on the iPad not in the simulator, and I have a good network connection.
What am I missing?
Well apparently this was an email configuration problem with the iPad itself. After a reboot of the device the above code works perfectly. I absolutely hate this kind of problem.
Use the canSendMail method.
Use the following code to check if a device mail configuration is setup or not. Otherwise your app will crash.
if ([MFMailComposeViewController canSendMail])
{
// Create and show the MailComposeViewController
}
else
{
// Show No mail account set up on device.
}

In App Email - MFMailComposeViewController - Error Message

My code is as follows:
ViewController.m:
#import "ViewController.h"
#import "MyScene.h"
#import "MainMenu.h"
#import <MessageUI/MessageUI.h>
#implementation ViewController
- (IBAction)showMailPicker:(id)sender
{
// You must check that the current device can send email messages before you
// attempt to create an instance of MFMailComposeViewController. If the
// device can not send email messages,
// [[MFMailComposeViewController alloc] init] will return nil. Your app
// will crash when it calls -presentViewController:animated:completion: with
// a nil view controller.
if ([MFMailComposeViewController canSendMail])
// The device can send email.
{
[self displayMailComposerSheet];
}
else
// The device can not send email.
{
self.feedbackMsg.hidden = NO;
self.feedbackMsg.text = #"Device not configured to send mail.";
}
}
- (IBAction)showSMSPicker:(id)sender
{
// You must check that the current device can send SMS messages before you
// attempt to create an instance of MFMessageComposeViewController. If the
// device can not send SMS messages,
// [[MFMessageComposeViewController alloc] init] will return nil. Your app
// will crash when it calls -presentViewController:animated:completion: with
// a nil view controller.
if ([MFMessageComposeViewController canSendText])
// The device can send email.
{
[self displaySMSComposerSheet];
}
else
// The device can not send SMS.
{
self.feedbackMsg.hidden = NO;
self.feedbackMsg.text = #"Device not configured to send SMS.";
}
}
- (void)displayMailComposerSheet
{
MFMailComposeViewController *picker = [[MFMailComposeViewController alloc] init];
picker.mailComposeDelegate = self;
[picker setSubject:#"Support for Brick Smasher Extreme"];
// Set up recipients
NSArray *toRecipients = [NSArray arrayWithObject:#"help.bricksx#gmail.com"];
//NSArray *ccRecipients = [NSArray arrayWithObjects:#"second#example.com", #"third#example.com", nil];
//NSArray *bccRecipients = [NSArray arrayWithObject:#"fourth#example.com"];
[picker setToRecipients:toRecipients];
//[picker setCcRecipients:ccRecipients];
//[picker setBccRecipients:bccRecipients];
// Attach an image to the email
//NSString *path = [[NSBundle mainBundle] pathForResource:#"rainy" ofType:#"jpg"];
//NSData *myData = [NSData dataWithContentsOfFile:path];
//[picker addAttachmentData:myData mimeType:#"image/jpeg" fileName:#"rainy"];
// Fill out the email body text
NSString *emailBody = #"Message:";
[picker setMessageBody:emailBody isHTML:YES];
//[self presentViewController:picker animated:YES completion:NULL];
[[[[[UIApplication sharedApplication] delegate] window] rootViewController] presentViewController:picker
animated:YES
completion:nil];
}
- (void)mailComposeController:(MFMailComposeViewController *)controller
didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error
{
self.feedbackMsg.hidden = NO;
// Notifies users about errors associated with the interface
switch (result)
{
case MFMailComposeResultCancelled:
self.feedbackMsg.text = #"Result: Mail sending canceled";
break;
case MFMailComposeResultSaved:
self.feedbackMsg.text = #"Result: Mail saved";
break;
case MFMailComposeResultSent:
self.feedbackMsg.text = #"Result: Mail sent";
break;
case MFMailComposeResultFailed:
self.feedbackMsg.text = #"Result: Mail sending failed";
break;
default:
self.feedbackMsg.text = #"Result: Mail not sent";
break;
}
[self dismissViewControllerAnimated:YES completion:NULL];
}
#end
The error is: Warning: Attempt to present <MFMailComposeViewController: 0xbf95170> on <UIViewController: 0xbf78d10> whose view is not in the window hierarchy!
I'm trying to send email through my app. Using MFMailComposeViewController, it always gives an error (above). But when I use the SMS part, there is no problem at all.
Using: Xcode 5, iOS 7, iPhone Retina 4"
Your problem is likely here:
[[[[[UIApplication sharedApplication] delegate] window] rootViewController] presentViewController:
First of all, you're already calling this from a ViewController, so you can just [self presentViewController:]. It does sound like maybe you're calling your displayMailComposerSheet before ViewController's view is visible (viewDidLoad or viewWillAppear maybe), which would raise the error you're seeing.
use
[self presentViewController:picker animated:YES completion:nil];
instead of
[[[[[UIApplication sharedApplication] delegate] window] rootViewController] presentViewController:picker animated:YES completion:nil];

In iOS 5.1 after dismissing MFMailComposeViewController my UIWebView page java script not working and not loading data from disc cache

I am opening web url in UIWebView which contains some buttons with java script actions. There is a button in this page email after hitting this button I get email address and email body in
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType{if( [requestString rangeOfString:#"email.com"].location!=NSNotFound){if ([MFMailComposeViewController canSendMail]){if (!mailer)
mailer = [[MFMailComposeViewController alloc] init];
mailer.mailComposeDelegate = self;
NSString *subject = [dataManager.dictTransalations objectForKey:#"71"];
[mailer setSubject:subject];
NSArray *toRecipients = [NSArray arrayWithObjects:distributorEmailAddress.length > 0 ? distributorEmailAddress:#"", nil];
[mailer setToRecipients:toRecipients];
[mailer setMessageBody:#"" isHTML:NO];
isFromMailVC=YES;
//[self presentViewController:mailer animated:YES completion:NULL];
[self presentModalViewController:mailer animated:YES];
}}return NO;}
- (void)mailComposeController(MFMailComposeViewController*)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error{
switch (result)
{
case MFMailComposeResultCancelled:
NSLog(#"Mail cancelled: you cancelled the operation and no email message was queued.");
break;
case MFMailComposeResultSaved:
NSLog(#"Mail saved: you saved the email message in the drafts folder.");
break;
case MFMailComposeResultSent:
NSLog(#"Mail send: the email message is queued in the outbox. It is ready to send.");
break;
case MFMailComposeResultFailed:
NSLog(#"Mail failed: the email message was not saved or queued, possibly due to an error.");
break;
default:
NSLog(#"Mail not sent.");
break;
}
[controller dismissModalViewControllerAnimated:YES];
NSLog(#" Mail Composer Error = %#",error);
}
After dismissing mailComposeController UIWebView java script does not work on other buttons and also in another tab hit another web url that contains some product list also shows blank with head image.
When I see the data in cache in documents directory its there in 100000.db for List table.
I don't why it does not load after opening and dismissing mailcompose. after quitting app from background it works.
Is there any way to debug UIWebView page in iOS 5.1 ?
I came across the same thing in iOS7 yesterday and found a solution a few minutes ago. Maybe it will help you.
Check your viewWillDisappear method. Mine looked like this:
- (void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
self.webView.delegate = nil;
self.webView = nil;
// whatever else you do
}
The error was in the assignments: when MFMailComposeViewController appeared and viewDidDisappear was called, webView lost its delegate and because of that clicks weren't captured.
If you're programming for iOS6 or newer, you should just leave it like that:
- (void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
// whatever else you do
}
But if you're programming for iOS5 or older and have to assign nil for some reason, then add this:
- (void)viewDidUnload
{
[super viewDidUnload];
self.webView.delegate = nil;
self.webView = nil;
// whatever else you do
}
Note: this method is deprecated for iOS6 and newer, as it is never called since iOS6.