How can I send emails from my custom UIActivity class? - ios

I made a costume UIActivity class. I like to send emails with attachments with the class, but I can't send emails, or present any ViewControllers from the class. I am trying to present the Mail ViewController with this:
- (void)prepareWithActivityItems:(NSArray *)activityItems
{
NSString *subject = [NSString stringWithFormat:#"%#", [self.filePath lastPathComponent]];
NSString *messageBody = [NSString stringWithFormat:#"%# was extracted with #FilyForiOS, visit", [self.filePath lastPathComponent]];
NSData *attachment = [NSData dataWithContentsOfFile:self.filePath];
MFMailComposeViewController *mc = [[MFMailComposeViewController alloc] init];
mc.mailComposeDelegate = self;
[mc setSubject:subject];
[mc setMessageBody:messageBody isHTML:NO];
[mc setToRecipients:nil];
[mc addAttachmentData:attachment mimeType:[[self.filePath lastPathComponent] pathExtension] fileName:[self.filePath lastPathComponent]];
[self presentViewController:mc animated:YES completion:nil]; // Here is the error: No visible #interface for 'MailTo' declares the selector 'presentViewController:animated:completion:'
}
Can anyone tell me how I can present a ViewController from this class?
I used this code: How can I create a custom UIActivity in iOS?

Sorry that I'm just now answering this (I know this was asked along time ago) But here is my answer:
#import <MessageUI/MessageUI.h>
#interface EmailActivity : UIActivity <MFMailComposeViewControllerDelegate>
#end
#implementation EmailActivity
- (NSString *)activityTitle
{
// Your title
return #"Email";
}
- (UIImage *)activityImage
{
// Your image
return [UIImage imageNamed:#"Email"];
}
- (BOOL)canPerformWithActivityItems:(NSArray *)activityItems
{
return YES;
}
- (void)mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error
{
[self activityDidFinish:YES];
}
- (UIViewController *)activityViewController
{
MFMailComposeViewController *mc = [[MFMailComposeViewController alloc]init];
if ([MFMailComposeViewController canSendMail])
{
NSString *subject = [NSString stringWithFormat:#"%#", [self.filePath lastPathComponent]];
NSString *messageBody = [NSString stringWithFormat:#"%# was extracted with #FilyForiOS, visit", [self.filePath lastPathComponent]];
NSData *attachment = [NSData dataWithContentsOfFile:self.filePath];
[mc setSubject:subject];
[mc setMessageBody:messageBody isHTML:NO];
[mc setToRecipients:nil];
[mc addAttachmentData:attachment mimeType:[[self.filePath lastPathComponent] pathExtension] fileName:[self.filePath lastPathComponent]];
mc.mailComposeDelegate = self;
return mc;
}
else
{
return nil;
}
}
#end

Related

UIButton's IBAction only works the first time it is tapped

Using Apple's template "Tabbed Bar Banner" I found that the button in one of the views only works the first times I pressed it.
If the iPhone is connected to Xcode to run the app, it works great. Once I have detached the cable, the button stops working.
- (IBAction)sendData:(id)sender {
UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
imagePicker.delegate = self;
imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;
imagePicker.allowsEditing = YES;
[self presentViewController:imagePicker animated:YES completion:nil];
}
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
selectedImage = [info objectForKey:UIImagePickerControllerOriginalImage];
[self dismissViewControllerAnimated:YES completion:^{
[self openEmail];
}];
}
-(IBAction) openEmail {
MFMailComposeViewController *mailComposer = [[MFMailComposeViewController alloc] init];
[mailComposer setMailComposeDelegate:self];
if ([MFMailComposeViewController canSendMail]) {
[mailComposer setToRecipients:[NSArray arrayWithObjects:#"*******", nil]];
[mailComposer setSubject:self.nameTextField.text];
NSLog(#"self.nameTextField.text = %#", *********);
[mailComposer setMessageBody:#"******r" isHTML:NO];
[mailComposer setModalTransitionStyle:UIModalTransitionStyleCrossDissolve];
NSString *path = [[NSBundle mainBundle] pathForResource:#"Answer" ofType:#"plist"];
NSData *myData = [NSData dataWithContentsOfFile:path];
[mailComposer addAttachmentData:myData mimeType:#"application/xml" fileName:#"Answer.plist"];
NSData *imageData = UIImageJPEGRepresentation(selectedImage, 0.5);
[mailComposer addAttachmentData:imageData mimeType:#"image/jpg" fileName:[NSString stringWithFormat:#"%#.jpg",*********]];
[self composeCSV];
NSString *fileName = [file lastPathComponent];
[mailComposer addAttachmentData:[NSData dataWithContentsOfFile:file] mimeType:#"text/csv" fileName:fileName];
[self presentViewController:mailComposer animated:YES completion:nil];
}
}
- (void)mailComposeController:(MFMailComposeViewController*)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error
{
[self dismissViewControllerAnimated:YES completion:nil];
}
- (void)composeCSV{
NSMutableString *mainString = [[ NSMutableString alloc]initWithString:#"++;++;++;++;...\n"];
[mainString appendFormat:#"%#;\n",...];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectoryPath = [paths objectAtIndex:0];
file = [NSString stringWithFormat:#"%#/%#.csv",documentsDirectoryPath,******];
NSError *csVerror= NULL;
BOOL written = [mainString writeToFile:file atomically:YES encoding:NSUTF8StringEncoding error:&csVerror];
if (!written) {
NSLog( #"Writing failed, error = %#",csVerror);
}else {
NSLog(#"Data saved! File path = %#",file);
}
}

ImagePicker captures photo, but can't save to Album

I already wrote this code to make a profile photo for my app and it doesn't work. Been searching for different sources and couldn't find any.Please help. I can take a photo but it doesn't get saved on the Album and a photo can't be uploaded or saved on the UIImageView for the profile.
#import "ViewController.h"
#interface ViewController ()
{
UIImage *originalImage;
}
#property(nonatomic, weak) IBOutlet UIImageView *selectedImageView;
#property(nonatomic, weak) IBOutlet UIBarButtonItem *saveButton;
#end
#implementation ViewController
#synthesize selectedImageView, saveButton;
- (IBAction)photoFromAlbum
{
UIImagePickerController *photoPicker = [[UIImagePickerController alloc] init];
photoPicker.delegate = self;
photoPicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
[self presentViewController:photoPicker animated:YES completion:NULL];
}
- (IBAction)photoFromCamera
{
UIImagePickerController *photoPicker = [[UIImagePickerController alloc] init];
photoPicker.delegate = self;
photoPicker.sourceType = UIImagePickerControllerSourceTypeCamera;
[self presentViewController:photoPicker animated:YES completion:NULL];
}
- (void)imagePickerController:(UIImagePickerController *)photoPicker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
self.saveButton.enabled = YES;
originalImage = [info valueForKey:UIImagePickerControllerOriginalImage];
[self.selectedImageView setImage:originalImage];
// [photoPicker dismissModalViewControllerAnimated:YES];
}
- (IBAction)saveImageToAlbum
{
UIImageWriteToSavedPhotosAlbum(self.selectedImageView.image, self, #selector(image:didFinishSavingWithError:contextInfo:), nil);
}
- (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo
{
NSString *alertTitle;
NSString *alertMessage;
if(!error)
{
alertTitle = #"Image Saved";
alertMessage = #"Image saved to photo album successfully.";
}
else
{
alertTitle = #"Error";
alertMessage = #"Unable to save to photo album.";
}
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:alertTitle
message:alertMessage
delegate:self
cancelButtonTitle:#"Okay"
otherButtonTitles:nil];
[alert show];
}
- (UIImage*)loadImage
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString* path = [documentsDirectory stringByAppendingPathComponent:
[NSString stringWithString: #"test.png"] ];
UIImage* image = [UIImage imageWithContentsOfFile:path];
return image;
}
#end

iOS: file name in email attachment

I can send a .csv file as an attachment from my app, but I'd like to shorten the name file for that attachment, because there will be a pile of csv files delivered to the recipient.
Piece of code:
...
if (dorsalesPorTramoYcontrol && dorsalesPorTramoYcontrol.count )
{
NSMutableString *mainString = [[ NSMutableString alloc]initWithString:#"dorsal,paso,tiempo\n"];
for (NSManagedObject *get in dorsalesPorTramoYcontrol) {
//dorsales
NSString *string =[get valueForKey:#"dorsal"];
[mainString appendFormat:#"%#,",string];
//paso
string = [get valueForKey:#"paso"];
string=[string stringByReplacingOccurrencesOfString:#"\"" withString:#"\"\""];
[mainString appendFormat:#"%#,",string];
//tiempo
string = [get valueForKey:#"tiempo"];
string=[string stringByReplacingOccurrencesOfString:#"\"" withString:#"\"\""];
[mainString appendFormat:#"%#",string];
[mainString appendFormat:#"\n"];
}
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectoryPath = [paths objectAtIndex:0];
file = [NSString stringWithFormat:#"%#/Tramo%#Control%#.csv", documentsDirectoryPath,section,control];
NSError *csVerror= NULL;
BOOL written = [mainString writeToFile:file atomically:YES encoding:NSUTF8StringEncoding error:&csVerror];
if (!written) {
NSLog( #"Writing failed, error = %#",csVerror);
}else {
NSLog(#"Data saved! File path = %#",file);
[self composeEmail];
}
}
}
-(void)composeEmail{
if ([MFMailComposeViewController canSendMail])
{
MFMailComposeViewController *mailer = [[MFMailComposeViewController alloc] init];
mailer.mailComposeDelegate = self;
[mailer setSubject:[NSString stringWithFormat:#"Resultados Tramo: %# - Control: %#", section, control]];
NSArray *toRecipients = [NSArray arrayWithObjects:#"somebodymail#mail.com", nil];
[mailer setToRecipients:toRecipients];
// Logo
UIImage *myImage = [UIImage imageNamed:#"logo.png"];
NSData *imageData = UIImagePNGRepresentation(myImage);
[mailer addAttachmentData:imageData mimeType:#"image/png" fileName:#"Icon"];
[mailer addAttachmentData:[NSData dataWithContentsOfFile:file] mimeType:#"text/csv" fileName:file];
NSString *emailBody =
[NSString stringWithFormat:#"Resultados Tramo: %# - Control: %# \nDorsal - Paso - Tiempo", section, control];
[mailer setMessageBody:emailBody isHTML:NO];
mailer.modalPresentationStyle = UIModalPresentationPageSheet;
[self presentViewController:mailer animated:YES completion:nil];
}
else
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Failure"
message:#"Your device doesn't support the composer sheet"
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles: nil];
[alert show];
}
}
The filename is the following:
<_var_mobile_Applications_BE8CE610-A83E-4C79-8B9C-0263FA6881D6_Documents_Tramo2Control4.csv>
and I'd like it to be just "Tramo2Control4.csv"
Could you please offer some suggestions to get it?
Change the following line:
[mailer addAttachmentData:[NSData dataWithContentsOfFile:file] mimeType:#"text/csv" fileName:file];
To:
NSString *fileName = [file lastPathComponent];
[mailer addAttachmentData:[NSData dataWithContentsOfFile:file] mimeType:#"text/csv" fileName:fileName];
You were originally setting the file name to be the entire file path.

Attach an image to an email

I was wondering if there is a way to allow the user to select an image from the camera roll, and then attach it to an email?
Here is the code I have now:
-(IBAction) openEmail {
MFMailComposeViewController *mailComposer = [[MFMailComposeViewController alloc] init];
[mailComposer setMailComposeDelegate:self];
if ([MFMailComposeViewController canSendMail]) {
[mailComposer setToRecipients:[NSArray arrayWithObjects:#"TPsecondary_Example#email.com", nil]];
[mailComposer setSubject:#"Learning Trail Submission"];
[mailComposer setMessageBody:emailbody isHTML:NO];
[mailComposer setModalTransitionStyle:UIModalTransitionStyleCrossDissolve];
NSString *path = [[NSBundle mainBundle] pathForResource:#"Answer" ofType:#"plist"];
NSData *myData = [NSData dataWithContentsOfFile:path];
[mailComposer addAttachmentData:myData mimeType:#"application/xml" fileName:#"Answer.plist"];
[self presentModalViewController:mailComposer animated:YES];
}
}
There sure is!
In your .h file add these delegates and declare a UIImage named selectedImage.
<UIImagePickerControllerDelegate, UINavigationControllerDelegate>
Then in your .m you can add the following.
Link -(IBAction)openImagePicker:(id)sender to the button that you want to start the process.
- (IBAction)openImagePicker:(id)sender
{
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary])
{
UIImagePickerController *imagePicker =
[[UIImagePickerController alloc] init];
imagePicker.delegate = self;
imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;
imagePicker.allowsEditing = NO;
[self presentViewController:imagePicker animated:YES completion:nil];
}
}
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
selectedImage = [info objectForKey:UIImagePickerControllerOriginalImage];
[self dismissViewControllerAnimated:YES completion:^{
[self openEmail];
}];
}
-(IBAction) openEmail {
MFMailComposeViewController *mailComposer = [[MFMailComposeViewController alloc] init];
[mailComposer setMailComposeDelegate:self];
if ([MFMailComposeViewController canSendMail]) {
[mailComposer setToRecipients:[NSArray arrayWithObjects:#"TPsecondary_Example#email.com", nil]];
[mailComposer setSubject:#"Learning Trail Submission"];
[mailComposer setMessageBody:emailbody isHTML:NO];
[mailComposer setModalTransitionStyle:UIModalTransitionStyleCrossDissolve];
NSString *path = [[NSBundle mainBundle] pathForResource:#"Answer" ofType:#"plist"];
NSData *myData = [NSData dataWithContentsOfFile:path];
[mailComposer addAttachmentData:myData mimeType:#"application/xml" fileName:#"Answer.plist"];
NSData *imageData = UIImageJPEGRepresentation(selectedImage, 1.0);
[mailComposer addAttachmentData:imageData mimeType:#"image/jpg" fileName:#"imageTitle"];
[self presentModalViewController:mailComposer animated:YES];
}
}
EDIT: Mind you this is a very basic example that doesn't handle events such as the user selecting a video instead of an image...

Email CSV file with MFMailComposer

I would like to create a file using a NSString (already made) with a .csv extension then email it using the UIMessage framework. So can someone show me the code to create a file (with a .csv extensions and with the contents of a NSString) then how to attach it to a MFMailComposeViewController.
This is how you attach a CSV file to a MFMailComposeViewController:
MFMailComposeViewController *mailer = [[MFMailComposeViewController alloc] init];
mailer.mailComposeDelegate = self;
[mailer setSubject:#"CSV File"];
[mailer addAttachmentData:[NSData dataWithContentsOfFile:#"PathToFile.csv"]
mimeType:#"text/csv"
fileName:#"FileName.csv"];
[self presentModalViewController:mailer animated:YES];
// Note: PathToFile.csv is the actual path of the file on your iOS device's
// file system. FileName.csv is what it should be displayed as in the email.
As far as how to generate the CSV file itself, the CHCSVWriter class at https://github.com/davedelong/CHCSVParser will help you.
Here are the parts where you create a new csv, save it to file and attach it all in one. You know, if you're in to that sort of thing
NSString *emailTitle = #"My Email Title";
NSString *messageBody = #"Email Body";
MFMailComposeViewController *mc = [[MFMailComposeViewController alloc] init];
mc.mailComposeDelegate = self;
[mc setSubject:emailTitle];
[mc setMessageBody:messageBody isHTML:NO];
[mc setToRecipients:#[]];
NSMutableString *csv = [NSMutableString stringWithString:#""];
//add your content to the csv
[csv appendFormat:#"MY DATA YADA YADA"];
NSString* filePath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString* fileName = #"MyCSVFileName.csv";
NSString* fileAtPath = [filePath stringByAppendingPathComponent:fileName];
if (![[NSFileManager defaultManager] fileExistsAtPath:fileAtPath]) {
[[NSFileManager defaultManager] createFileAtPath:fileAtPath contents:nil attributes:nil];
}
BOOL res = [[csv dataUsingEncoding:NSUTF8StringEncoding] writeToFile:fileAtPath atomically:NO];
if (!res) {
[[[UIAlertView alloc] initWithTitle:#"Error Creating CSV" message:#"Check your permissions to make sure this app can create files so you may email the app data" delegate:nil cancelButtonTitle:#"Okay" otherButtonTitles: nil] show];
}else{
NSLog(#"Data saved! File path = %#", fileName);
[mc addAttachmentData:[NSData dataWithContentsOfFile:fileAtPath]
mimeType:#"text/csv"
fileName:#"MyCSVFileName.csv"];
[self presentViewController:mc animated:YES completion:nil];
}

Resources