I have seen a nice feature in the iOS App Scanner Pro. This app allows to send scanned documents as email attachments via the original mail app from Apple but without leaving the Scanner Pro app. I ask me how did they do it? Is there a special API call?
implement MFMailComposeViewControllerDelegate like this:
#interface YourViewController<MFMailComposeViewControllerDelegate >
Then where you want to instantiate this email viewcontroller just do the following:
if([MFMailComposeViewController canSendMail])
{
MFMailComposeViewController *mailController = [[MFMailComposeViewController alloc] init];
[mailController setMailComposeDelegate:self];
[mailController setSubject:#"Mail Subject!"];
[mailController setMessageBody:#"Here is your message body" isHTML:NO];
[mailController setToRecipients:[NSArray arrayWithObject:#"yourrecipent#domain.com"]];
NSData *imageData = UIImageJPEGRepresentation(imageToUpload, 1.0f);
if(imageData.length)
{
[mailController addAttachmentData:imageData mimeType:#"image/jpeg" fileName:#"Your_Photo.jpg"];
[self presentModalViewController:mailController animated:YES];
}
else
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Invalid Image" message:#"The image couldn't be converted." delegate:nil cancelButtonTitle:nil otherButtonTitles:#"Okay", nil];
[alert show];
}
}
Last implement mailComposerViewController delegate method
-(void)mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error
{
[self dismissViewControllerAnimated:YES completion:nil];
// or you can check for the status first and implement different task if you wish
}
You can use UIActivityViewController, for example:
UIImage *image = [UIImage imageNamed:#"image_file_name"];
UIActivityViewController *activityViewController = [[UIActivityViewController alloc] initWithActivityItems:#[image] applicationActivities:nil];
[self presentViewController:activityViewController animated:YES completion:nil];
it gives user even more options, than just send email.
Yes, the so called UIActivityViewController. You use it like this:
NSArray *itemsToShare = #[[NSString stringWithFormat:#"This is a string that is sent via mail as well."], NSURLtoTheFileToSend];
UIActivityViewController *activityVC = [[UIActivityViewController alloc] initWithActivityItems:itemsToShare applicationActivities:nil];
activityVC.excludedActivityTypes = #[UIActivityTypeAssignToContact]; // Here you can say what you dont want to give the opportunity to share.
activityVC.completionHandler = ^(NSString *activityType, BOOL completed) {
if (completed) {
UIAlertView *alert = [[UIAlertView alloc] init];
alert.title = #"Export successfull";
[alert show];
[alert performSelector:#selector(dismissWithClickedButtonIndex:animated:) withObject:nil afterDelay:1];
}
};
[self presentViewController:activityVC animated:YES completion:^{}];
Related
I want to send an image with my text Message. I have used MFMessageComposeViewController. This is the code i have done:
MFMessageComposeViewController *messageController = [[MFMessageComposeViewController alloc] init];
messageController.messageComposeDelegate = self;
NSArray *recipents = #[[arr_promoterDetaildata valueForKey:#"phone_number"], #"72345524"];
UIImage *img = [UIImage imageNamed:#"ic_dummy_img"];
NSData *imgData = UIImagePNGRepresentation(img);
BOOL didAttachImage = [messageController addAttachmentData:imgData typeIdentifier:(NSString *)kUTTypePNG filename:#"image.png"];
NSString *message = [NSString stringWithFormat:#"Sending SMS"];
[messageController setRecipients:recipents];
[messageController setBody:message];
if (didAttachImage)
{
// Present message view controller on screen
[self presentViewController:messageController animated:YES completion:nil];
}
else
{
UIAlertView *warningAlert = [[UIAlertView alloc] initWithTitle:#"Error"
message:#"Failed to attach image"
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[warningAlert show];
return;
}
I have tried so many method’s but it is not attaching image in my message screen. Can anyone help?
Here is my code
-(IBAction)emailButtonPressed :(UIButton *)sender {
if (![MFMailComposeViewController canSendMail]) {
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:nil message:#"Mail has not been set up on this device" delegate:nil cancelButtonTitle:#"Ok" otherButtonTitles:nil];
[alertView show];
return;
}
NSString *targetFile = [self saveCompleteImage];
MFMailComposeViewController *mailpicker = [[MFMailComposeViewController alloc] init];
[mailpicker setMailComposeDelegate:self];
NSString *mimeType = [StringHelper getMimeType:targetFile];
[mailpicker addAttachmentData:[NSData dataWithContentsOfFile:targetFile] mimeType:mimeType fileName:[targetFile lastPathComponent]];
[mailpicker setSubject:[self.currentDocument getNameForUntitled]];
mailpicker.modalPresentationStyle = UIModalPresentationFormSheet;
[self.presentedViewController presentViewController:mailpicker animated:YES completion:nil];
}
It's not presenting mailpicker. Kindly tell me where am i wrong.
Issue is with this code:
[self.presentedViewController presentViewController:mailpicker animated:YES completion:nil];
You need to use:
[self presentViewController:mailpicker animated:YES completion:nil];
or
[self.presentingViewController presentViewController:mailpicker animated:YES completion:nil];
Check ModalViewControllers Reference to understand the difference between presentedViewController and presentingViewController
Iam presenting MFMailComposeViewController from my custom class(not a viewController). In iOS5 it is working fine but in iOS6 it is getting crash immediately after presenting the compose sheet. I found the issue the dealloc method is getting called after presenting the view, so self is deallocating. Due to this mailcomposer cannot call the delegate method on self so it is crashing. I didnt get a solution for that. Am using ARC. How to prevent self from deallocating until the delegate method is getting called?
-(void)shareOnViewController:(UIViewController *)viewController completion:(ShareCompletionHandler)completion
{
if ([MFMailComposeViewController canSendMail]) {
MFMailComposeViewController *mailer = [[MFMailComposeViewController alloc] init];
mailer.mailComposeDelegate = self;
mailer.modalPresentationStyle = UIModalPresentationPageSheet;
[mailer setSubject:[self.userInfo objectForKey:#"title"]];
NSData *imageData = UIImagePNGRepresentation([self.userInfo objectForKey:#"image"]);
if (imageData) {
[mailer addAttachmentData:imageData mimeType:#"image/png" fileName:#"AttachedImage"];
}
NSURL *emailBody = [self.userInfo objectForKey:#"url"];
if (![emailBody isEqual:#""]) {
[mailer setMessageBody:[emailBody absoluteString] isHTML:NO];
}
[viewController presentModalViewController:mailer animated:YES];
} else {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Unable to send mail"
message:#"Device is not configured to send mail"
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
}
self.completionHandler = completion;
}
According to me , The presentModalViewController method is deprecated in iOS 6.0 .
Instead you need to use
- (void)presentViewController:(UIViewController *)viewControllerToPresent animated: (BOOL)flag completion:(void (^)(void))completion
Else can you show the crash log ??
if ([MFMailComposeViewController canSendMail]) {
MFMailComposeViewController *mailComposer = [[MFMailComposeViewController alloc]
init];
NSData *imageData = UIImagePNGRepresentation(image);
mailComposer.mailComposeDelegate = self;
[mailComposer setSubject:subject];
NSArray * recipents = [NSArray arrayWithObjects:[NSString stringWithFormat:#"%#",NSLocalizedString(#"client_email", #"")],nil];
[mailComposer setToRecipients:recipents];
[mailComposer addAttachmentData:imageData mimeType:#"image/png" fileName:[NSString stringWithFormat:#"imageProfile-%#-%#",someId,lastname]];
mailComposer.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[vc presentViewController:mailComposer animated:YES completion:nil];
}
else
{
UIAlertView *tmp = [[UIAlertView alloc]
initWithTitle:#"Email Account Not Found"
message:#"You need to setup an Email Account!"
delegate:self
cancelButtonTitle:nil
otherButtonTitles:#"Ok", nil];
[tmp show];
}
One of the possible root cause is ARC.
MFMailComposeViewController *mailer = [[MFMailComposeViewController alloc] init];
mailer will be auto-released as soon as the method body is fully executed.
You could create a reference to hold the object to avoid ARC releasing it before it is ready.
#property (nonatomic, strong) MFMailComposeViewController * composer;
....
self.composer = [[MFMailComposeViewController alloc] init];
...
[viewController presentViewController:self.composer animated:YES];
[Edited suggestion]
Sorry, I miss out the first part of your question where you were calling the method from another custom class.
I came across the similar situation also. In the end, I converted the "Custom Class" into a Singleton class.
#pragma mark Singleton Methods
+ (id)sharedInstance {
static CustomClass *sharedInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedInstance = [[self alloc] init];
});
return sharedInstance;
}
This will make sure the class will be retained nicely. But this will depend on the usage and design of the CustomClass. Just to share what I did.
[[CustomClass sharedInstance] shareOnViewController:vc completion:...];
I get to the Mail program fine, and when I press "Send" I hear the swoosh sound and Mail closes and returns me to my app, but the actual mail isn't sending.
Here's the code I'm using to mail. Any ideas about what I'm doing wrong?
(I'm using iOS6, on an actual device, not the simulator.)
-(void)openMail {
//Open Mail program and create email with haiku attached as image.
if ([MFMailComposeViewController canSendMail])
{
MFMailComposeViewController *mailer = [[MFMailComposeViewController alloc] init];
mailer.mailComposeDelegate = self;
[mailer setSubject:[NSString stringWithFormat:#"subject"]];
UIImage *myImage = [self createImage];
NSData *imageData = UIImagePNGRepresentation(myImage);
[mailer addAttachmentData:imageData mimeType:#"image/jpg" fileName:#"xxxxx"];
NSString *emailBody = #"I thought you might like this haiku from the xxxxx iPhone app.";
[mailer setMessageBody:emailBody isHTML:NO];
[self presentViewController:mailer animated:YES completion:NULL];
}
//Unless it's not possible to do so, in which case show an alert message.
else
{
self.alert = [[UIAlertView alloc] initWithTitle:#"I'm sorry." message:#"Your device doesn't seem to be able to email this haiku. Perhaps you'd like to tweet it or post it on Facebook instead?" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles: nil];
[self.alert show];
}
}
-(void)mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error {
[self dismissViewControllerAnimated:YES completion:Nil];
}
It looks like it's actually a problem between my server and the iOS 6.1 update. I'll leave this up in case other people have the same problem. If the issue is fixed and my email STILL won't send, then I'll post another question.
i am a newbie to iOS and am trying to add inapt email in my app. I have a screen in which pushing the email icon should open the inapp email. I have the code for the inapp email. However, the button is already an outlet on the controller. So, I don't know how to link the same button to a different class/file which has the code for the inapp email. I was thinking of setting up a delegate but don't know how to initialize the delegate in the mail class. Have been struggling for a few days...please help!
Sumit
Try MFMailComposeViewController.... here is some sample code:
Make sure you import the MEssageUI framework and import the MFMailComposeViewController/MessageUI in .h and also conform to its delegate
MFMailComposeViewController *mailView = [[MFMailComposeViewController alloc] init];
[mailView setMailComposeDelegate:self];
if ([MFMailComposeViewController canSendMail]) {
[mailView setSubject:#"Interesting Apple News Article!"];
NSString *mailString = [[NSString alloc] initWithFormat:#"Test!"];
[mailView setMessageBody:mailString isHTML:NO];
[mailView setModalTransitionStyle:UIModalTransitionStyleCoverVertical];
[self presentModalViewController:mailView animated:YES];
[mailString release];
[mailView release];
} else
[mailView release];
}
-(void)mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error {
if (error) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Mailing Error" message:[error localizedDescription] delegate:self cancelButtonTitle:#"Dismiss" otherButtonTitles:nil, nil];
[alert show];
[alert release];
[self dismissModalViewControllerAnimated:YES];
} else {
[self dismissModalViewControllerAnimated:YES];
}
}