When writing data into a plist what type would an email be? - iphone

I'm in the process of using a plist to populate a uitableview. I was wondering, because one of my keys is email, what type would it be? Data, string, etc. The basic idea is to have a table, you tap the email cell, and up comes with the email modal view. How do i go about doing this?
Thanks

The data type I would use would be a string. You can then pull out this string and use it where you need it. In the case of email, you will need to do the following (I am assuming you are able to read the string out of the plist and use it within a UITableViewCell):
#pragma mark -
#pragma mark Compose Mail
-(void)callMailComposer
{
Class mailClass = (NSClassFromString(#"MFMailComposeViewController"));
if (mailClass != nil)
{
// We must always check whether the current device is configured for sending emails
if ([mailClass canSendMail])
{
[self displayComposerSheet];
}
else
{
[self launchMailAppOnDevice];
}
}
else
{
[self launchMailAppOnDevice];
}
}
// Displays an email composition interface inside the application. Populates all the Mail fields.
-(void)displayComposerSheet
{
MFMailComposeViewController *picker = [[MFMailComposeViewController alloc] init];
picker.mailComposeDelegate = self;
[picker setSubject:#"My email subject"];
//Just an extra example if you were wanting to add an attachment :)
/* NSString* pdfFileName = #"pdf_file.pdf";
NSArray* documentDirectories = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask,YES);
NSString* documentDirectory = [documentDirectories objectAtIndex:0];
NSString* documentDirectoryFilename = [documentDirectory stringByAppendingPathComponent:pdfFileName];
[picker addAttachmentData:[NSData dataWithContentsOfFile:documentDirectoryFilename] mimeType:#"application/pdf" fileName:pdfFileName]; */
// Set up recipients
[picker setCcRecipients:nil];
[picker setBccRecipients:nil];
[picker setToRecipients:[NSArray arrayWithObjects:#"myEmailAddressFromPlist",nil]];
NSString *emailBody = #"Hey you got mail";
[picker setMessageBody:emailBody isHTML:YES];
[self presentModalViewController:picker animated:YES];
[picker release];
picker=nil;
}
// Dismisses the email composition interface when users tap Cancel or Send. Proceeds to update the message field with the result of the operation.
- (void)mailComposeController:(MFMailComposeViewController*)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error
{
NSString* alertMessage;
// Notifies users about errors associated with the interface
switch (result)
{
case MFMailComposeResultCancelled:
alertMessage = #"Email composition cancelled";
break;
case MFMailComposeResultSaved:
alertMessage = #"Your e-mail has been saved successfully";
break;
case MFMailComposeResultSent:
alertMessage = #"Your email has been sent successfully";
break;
case MFMailComposeResultFailed:
alertMessage = #"Failed to send email";
break;
default:
alertMessage = #"Email Not Sent";
break;
}
UIAlertView* alertView = [[UIAlertView alloc] initWithTitle:#"My application" message:alertMessage delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alertView show];
[alertView release];
[self dismissModalViewControllerAnimated:YES];
}
#pragma mark Workaround
// Launches the Mail application on the device.
-(void)launchMailAppOnDevice
{
//You will need to fill these in
NSString *recipients = #"mailto:?cc=&subject=";
NSString *body = #"&body=";
NSString *email = [NSString stringWithFormat:#"%#%#", recipients, body];
email = [email stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:email]];
}

Related

how to set email Receptionit a NSString in iphone application

I am sending email from iphone app and i want that email sent to should be the value or address the var emailTO has should be in TO automatically.
NSString*emailTO=#"ali#yahoo.com";
[picker setRecipients:[NSArray arrayWithObject:emailTO]];
but it does not work any idea how to implement in this way thanks
MFMailComposeViewController *picker = [[MFMailComposeViewController alloc] init];
picker.mailComposeDelegate = self;
[picker setToRecipients:[NSArray arrayWithObject:[NSString stringWithFormat:#"%#,#"ur Receipent data"]]]];
Try to use this one...
NSArray *array = [NSArray arrayWithObject:#"ali#yahoo.com"];
if ([MFMailComposeViewController canSendMail])
{
MFMailComposeViewController *mailViewController = [[MFMailComposeViewController alloc] init];
mailViewController.mailComposeDelegate = self;
[mailViewController setToRecipients:array];
[self presentViewController:mailViewController animated:YES completion:NULL];
}
else
{
NSLog(#"Device is unable to send email in its current state.");
}
Try This. Hope will Help You.Note that you will need to add the MessageUI framework to your app.
#import <MessageUI/MessageUI.h>
and
MFMailComposeViewController *mail = [[[MFMailComposeViewController alloc] init] autorelease];
mail.mailComposeDelegate = self;
[mail setToRecipients:[NSArray arrayWithObject:#"email#gmail.com"]];
[mail setSubject:#"Set Your Subject Here"];
[self presentModalViewController:mail animated:YES];
Use MFMailComposeViewControllerDelegate protocol: Delegate Function for conform the result
- (void)mailComposeController:(MFMailComposeViewController*)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error
{
// Notifies users about errors associated with the interface
switch (result)
{
case MFMailComposeResultCancelled:
NSLog(#"Result: canceled");
break;
case MFMailComposeResultSaved:
NSLog(#"Result: saved");
break;
case MFMailComposeResultSent:
NSLog(#"Result: sent");
break;
case MFMailComposeResultFailed:
NSLog(#"Result: failed");
break;
default:
NSLog(#"Result: not sent");
break;
}
}
Description
setToRecipients:
Sets the initial recipients to include in the email’s “To” field.
- (void)setToRecipients:(NSArray*)toRecipients
Parameters
toRecipients
An array of NSString objects, each of which contains the email address of a single recipient.
try this
MFMailComposeViewController *mailViewController = [[MFMailComposeViewController alloc] init];
mailViewController.mailComposeDelegate = self;
[picker setRecipients:[NSArray arrayWithObject:#"your email address"]];
[self presentViewController:mailViewController animated:YES completion:nil];
If you want to open iPhone Email application, then use below code.So, you have not any need to add MFMailComposeViewController.
NSString *subject = #"";
NSString *body = #"";
NSString *address = #"test#gmail.com";
NSString *cc = #"";
NSString *path = [NSString stringWithFormat:#"mailto:%#?cc=%#&subject=%#&body=%#", address, cc, subject, body];
NSURL *url = [NSURL URLWithString:[path stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]]; [[UIApplication sharedApplication] openURL:url];
You should use
[picker setRecipients:[NSArray arrayWithObjects:emailTO,nil]];

Sync Events to available mail accounts in iphone

I am trying to sync Events added by my code in calendar application to available mail accounts. I just wanted to confirm that, is it possible in ios5?? I am trying to search for it but not able to find good solution for this. Any one having idea about this??
And I have one more question to ask that is, I am using ios5 new function which create new calendar in iphone's calendar application. Whenever I creates calendar of type local, I am able to create it. But I cant see that calendar in calendar list. Because of some reason it gets hide. Any idea about this??
Thank you in advance
First add MessageUI framework in your poject and import these two in your file
#import <MessageUI/MessageUI.h>
#import <MessageUI/MFMailComposeViewController.h>
Then make a button to refer mail in xid and link it with a IBAction (like below):
-(IBAction)emailSettings:(id)sender{
Class mailClass = (NSClassFromString(#"MFMailComposeViewController"));
if (mailClass != nil)
{
// check whether the current device is configured for sending emails
if ([mailClass canSendMail])
{
[self displayComposerSheet];
}
else
{
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:#"EMAIL" message:#"No Settings For Email" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
[alert show];
}
}
}
-(void)displayComposerSheet
{
MFMailComposeViewController *picker = [[MFMailComposeViewController alloc] init];
picker.mailComposeDelegate = self;
[picker setSubject:#"StampedeBreakfast!"];
// Set up recipients
NSArray *toRecipients = [NSArray arrayWithObject:#"first#example.com"];
NSArray *ccRecipients = [NSArray arrayWithObjects:#"second#example.com", nil];
NSArray *bccRecipients = [NSArray arrayWithObject:#"third#example.com"];
[picker setToRecipients:toRecipients];
[picker setCcRecipients:ccRecipients];
[picker setBccRecipients:bccRecipients];
// Fill out the email body text
NSString *emailBody = [NSString stringWithFormat:#"Hey! This is my Email Body"];
[picker setMessageBody:emailBody isHTML:NO];
[self presentModalViewController:picker animated:YES];
}
- (void)mailComposeController:(MFMailComposeViewController*)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error
{
switch (result)
{
case MFMailComposeResultCancelled:
NSLog( #"Result: canceled");
break;
case MFMailComposeResultSaved:
NSLog(#"Result: saved");
break;
case MFMailComposeResultSent:
NSLog(#"Result: sent");
break;
case MFMailComposeResultFailed:
NSLog( #"Result: failed");
break;
default:
NSLog(#"Result: not sent");
break;
}
[self dismissModalViewControllerAnimated:YES];
}
hope this will help you!!

iphone: How to add Email functionality in iPhone Ebook App

I m working on iPhone eBook app.
In my app books are created using HTML.
In Index.html page i have to put the email functionality which email(send) the contents of particular chapter.
Now by using webview i show the index.html and in that i have created UIActionSheet which will show the Email button.
Please suggest me that how can i identify the index of different links to send
email of particular chapter.
Below code will work even if you have not configured email in your device.
Here is the code:
- (IBAction) sendEmail:(id)sender
{
Class mailClass = (NSClassFromString(#"MFMailComposeViewController"));
if (mailClass != nil)
{
// We must always check whether the current device is configured for sending emails
if ([mailClass canSendMail])
{
[self displayComposerSheet];
}
else
{
[self launchMailAppOnDevice];
}
}
else
{
[self launchMailAppOnDevice];
}
}
-(void)displayComposerSheet
{
MFMailComposeViewController *picker = [[MFMailComposeViewController alloc] init];
picker.mailComposeDelegate = self;
[picker setSubject:#"Hello from DShah!"];
NSArray *toRecipients = [NSArray arrayWithObject:#"first#example.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];
NSString *path = [[NSBundle mainBundle] pathForResource:#"userdata" ofType:#"abc"];
NSFileManager *fileManager = [NSFileManager defaultManager];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *fullPath = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:#"%#.abc", #"userdata"]];
NSData *myData = [NSData dataWithContentsOfFile:fullPath];
[picker addAttachmentData:myData mimeType:#"csv" fileName:#"userdata.abc"];
NSString *emailBody = #"It is raining in sunny California!";
[picker setMessageBody:emailBody isHTML:NO];
[self presentModalViewController:picker animated:YES];
[picker release];
}
-(void)launchMailAppOnDevice
{
NSString *recipients = #"mailto:first#example.com&subject=Hello from DShah!";
NSString *body = #"&body=It is cold in Winter!";
NSString *email = [NSString stringWithFormat:#"%#%#", recipients, body];
email = [email stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:email]];
}
Then implement the Delegate method as below....
- (void)mailComposeController:(MFMailComposeViewController*)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error
{
switch (result)
{
case MFMailComposeResultCancelled:
message = #"Result: canceled";
break;
case MFMailComposeResultSaved:
message = #"Result: saved";
break;
case MFMailComposeResultSent:
message = #"Result: sent";
break;
case MFMailComposeResultFailed:
message = #"Result: failed";
break;
default:
message = #"Result: not sent";
break;
}
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Email Demo" message:message delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
[alert show];
[alert release];
[self dismissModalViewControllerAnimated:YES];
}
Check out Apple's MailComposer example. This will show you everything you need. http://developer.apple.com/library/ios/#samplecode/MailComposer/Introduction/Intro.html#//apple_ref/doc/uid/DTS40008865

Send an iphone attachment through email programmatically

I am writing an iPhone app that requires that I send an e-mail attachment programmatically. The attachment is a csv file, that I create through the code. I then attach the file to the email, and the attachment shows up on the phone. When I send the email to myself, however, the attachment doesn't appear in the e-mail. Here is the code I'm using.
[self exportData];
if ([MFMailComposeViewController canSendMail])
{
NSString *filePath = [[NSBundle mainBundle] pathForResource:#"expenses" ofType:#"csv"];
NSData *myData = [NSData dataWithContentsOfFile:filePath];
MFMailComposeViewController *mailer = [[MFMailComposeViewController alloc] init];
mailer.mailComposeDelegate = self;
[mailer setSubject:#"Vehicle Expenses from myConsultant"];
NSString *emailBody = #"";
[mailer setMessageBody:emailBody isHTML:NO];
[mailer addAttachmentData:myData mimeType:#"text/plain" fileName:#"expenses"];
[self presentModalViewController:mailer animated:YES];
[mailer release];
}
else
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Failure"
message:#"Your device doesn't support the composer sheet"
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
[alert release];
}
}
- (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;
}
// Remove the mail view
[self dismissModalViewControllerAnimated:YES];
The is being successfully created- I checked in the simulator files.
- (void) exportData
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory , NSUserDomainMask, YES);
NSString *documentsDir = [paths objectAtIndex:0];
NSString *root = [documentsDir stringByAppendingPathComponent:#"expenses.csv"];
NSString *temp=#"Date,Purpose,Start Odometer,End Odometer, Total Driven, Fees, ";
for(int i = 0; i < expenses.count; i++){
VehicleExpense *tempExpense = [expenses objectAtIndex:i];
temp = [temp stringByAppendingString:tempExpense.date];
temp = [temp stringByAppendingString:#", "];
temp = [temp stringByAppendingString:tempExpense.purpose];
temp = [temp stringByAppendingString:#", "];
temp = [temp stringByAppendingString:[NSString stringWithFormat: #"%.02f",tempExpense.start_mile]];
temp = [temp stringByAppendingString:#", "];
temp = [temp stringByAppendingString:[NSString stringWithFormat: #"%.02f",tempExpense.end_mile]];
temp = [temp stringByAppendingString:#", "];
temp = [temp stringByAppendingString:[NSString stringWithFormat: #"%.02f",tempExpense.distance]];
temp = [temp stringByAppendingString:#", "];
temp = [temp stringByAppendingString:[NSString stringWithFormat: #"%.02f",tempExpense.fees]];
temp = [temp stringByAppendingString:#", "];
}
[temp writeToFile:root atomically:YES encoding:NSUTF8StringEncoding error:NULL];
NSLog(#"got here in export data--- %#", documentsDir);
}
try
[mailer addAttachmentData:myData mimeType:#"text/csv" fileName:#"expenses.csv"];
Edit:
This is the code I'm using in my app:
- (IBAction) ExportData:(id)sender
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *filePath = [documentsDirectory stringByAppendingPathComponent:kExportFileName];
self.timeRecords = [[NSMutableArray alloc] init];
for (int i=0; i< [self.selectedTimeEntries count]; i++)
for (int j=0; j<[[self.selectedTimeEntries objectAtIndex:i] count]; j++)
if ([[self.selectedTimeEntries objectAtIndex:i] objectAtIndex:j] == [NSNumber numberWithBool:YES])
[self.timeRecords addObject:[self timeEntriesForDay:[self.uniqueArray objectAtIndex:i] forIndex:j]];
if( !([self.timeRecords count]!=0))
{
UIAlertView *alert=[[UIAlertView alloc] initWithTitle:#"There are no time entries selected!" message:#"Please select at least one time entry before proceeding" delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
[alert release];
return;
}
NSMutableString *csvLine;
NSError *err = nil;
NSDateFormatter* dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"yyyy-MM-dd"];
NSString *dateString = nil;
NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init];
[numberFormatter setPositiveFormat:#"###0.##"];
NSString *formattedNumberString = nil;
if(![[NSFileManager defaultManager] fileExistsAtPath:filePath])
{
[[NSFileManager defaultManager] createFileAtPath:filePath contents:nil attributes:nil];
}
for (timeEntries *timeEntry in self.timeRecords) {
csvLine = [NSMutableString stringWithString:timeEntry.client];
[csvLine appendString:#","];
[csvLine appendString:timeEntry.category];
[csvLine appendString:#","];
[csvLine appendString:timeEntry.task];
[csvLine appendString:#","];
dateString = [dateFormatter stringFromDate:[NSDate dateWithTimeIntervalSince1970:timeEntry.date]];
[csvLine appendString:dateString];
[csvLine appendString:#","];
formattedNumberString = [numberFormatter stringFromNumber:timeEntry.duration];
[csvLine appendString:formattedNumberString];
[csvLine appendString:#","];
[csvLine appendString:timeEntry.description];
[csvLine appendString:#"\n"];
if([[NSFileManager defaultManager] fileExistsAtPath:filePath])
{
NSString *oldFile = [[NSString alloc] initWithContentsOfFile:filePath];
[csvLine insertString:oldFile atIndex:0];
BOOL success =[csvLine writeToFile:filePath atomically:NO encoding:NSUTF8StringEncoding error:&err];
if(success){
}
[oldFile release];
}
}
if (!appDelegate.shouldSendCSV) {
self.csvText = csvLine;
}
if([[NSFileManager defaultManager] fileExistsAtPath:filePath])
{
[self emailExport:filePath];
}
self.selectedTimeEntries =nil;
self.navigationController.toolbarHidden = NO;
}
- (void)emailExport:(NSString *)filePath
{
NSLog(#"Should send CSV = %#", [NSNumber numberWithBool:appDelegate.shouldSendCSV]);
MFMailComposeViewController *picker = [[MFMailComposeViewController alloc] init];
picker.mailComposeDelegate = self;
// Set the subject of email
[picker setSubject:#"My Billed Time Export"];
// Add email addresses
// Notice three sections: "to" "cc" and "bcc"
NSString *valueForEmail = [[NSUserDefaults standardUserDefaults] stringForKey:#"emailEntry"];
NSString *valueForCCEmail = [[NSUserDefaults standardUserDefaults] stringForKey:#"ccEmailEntry"];
if( valueForEmail == nil || [valueForEmail isEqualToString:#""])
{
UIAlertView *alert=[[UIAlertView alloc] initWithTitle:#"Please set an email address before sending a time entry!" message:#"You can change this address later from the settings menu of the application!" delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
[alert release];
return;
}
else {
[picker setToRecipients:[NSArray arrayWithObjects:valueForEmail, nil]];
}
if(valueForCCEmail != nil || ![valueForCCEmail isEqualToString:#""])
{
[picker setCcRecipients:[NSArray arrayWithObjects:valueForCCEmail, nil]];
}
// Fill out the email body text
NSString *emailBody = #"My Billed Time Export File.";
// This is not an HTML formatted email
[picker setMessageBody:emailBody isHTML:NO];
if (appDelegate.shouldSendCSV) {
// Create NSData object from file
NSData *exportFileData = [NSData dataWithContentsOfFile:filePath];
// Attach image data to the email
[picker addAttachmentData:exportFileData mimeType:#"text/csv" fileName:#"MyFile.csv"];
} else {
[picker setMessageBody:self.csvText isHTML:NO];
}
// Show email view
[self presentModalViewController:picker animated:YES];
// Release picker
[picker release];
}
Dani's answer is great, however the code seems to be too long for someone looking for a simple way to send an attachment through email programatically.
The Gist
I pruned his answer to take out only the important bits, as well as refactored it like so:
MFMailComposeViewController *mailComposer = [[MFMailComposeViewController alloc] init];
mailComposer.mailComposeDelegate = self;
mailComposer.subject = #"Sample subject";
mailComposer.toRecipients = #[#"arthur#example.com", #"jeanne#example.com", ...];
mailComposer.ccRecipients = #[#"nero#example.com", #"mashu#example.com", ...];
[mailComposer setMessageBody:#"Sample body" isHTML:NO];
NSData *fileData = [NSData dataWithContentsOfFile:filePath];
[mailComposer addAttachmentData:fileData
mimeType:mimeType
fileName:fileName];
[self presentViewController:mailComposer animated:YES completion:nil];
That's basically the gist of it, this is enough as it is. If, for example, you put this code on a button's action, it will present an email composing screen with the respective fields pre-filled up, as well as having the file you want attached to the email.
Further Reading
Framework
The MFMailComposeViewController is under the MessageUI Framework, so to use it, import (if you have not done yet) the Framework like so:
#import <MessageUI/MessageUI.h>
Mail Capability Checking
Now when you run the source code, and you have not yet setup a mail account on your device, (not sure what the behavior is on simulator), this code will crash your app. It seems that if the mail account is not yet setup, doing [[MFMailComposeViewController alloc] init] will still result in the mailComposer being nil, causing the crash. As the answer in the linked question states:
You should check is MFMailComposeViewController are able to send your mail just before sending
You can do this by using the canSendMail method like so:
if (![MFMailComposeViewController canSendMail]) {
[self openCannotSendMailDialog];
return;
}
You can put this right before doing [[MFMailComposeViewController alloc] init] so that you can notify the user immediately.
Handling cannotSendMail
If canSendMail returns false, according to Apple Dev Docs, that means that the device is not configured for sending mail. This could mean that maybe the user has not yet setup their Mail account. To help the user with that, you can offer to open the Mail app and setup their account. You can do this like so:
NSURL *mailUrl = [NSURL URLWithString:#"message://"];
if ([[UIApplication sharedApplication] canOpenURL:mailUrl]) {
[[UIApplication sharedApplication] openURL:mailUrl];
}
You can then implement openCannotSendMailDialog like so:
- (void)openCannotSendMailDialog
{
UIAlertController *alert =
[UIAlertController alertControllerWithTitle:#"Error"
message:#"Cannot send mail."
preferredStyle:UIAlertControllerStyleAlert];
NSURL *mailUrl = [NSURL URLWithString:#"message://"];
if ([[UIApplication sharedApplication] canOpenURL:mailUrl]) {
[alert addAction:
[UIAlertAction actionWithTitle:#"Open Mail"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * _Nonnull action) {
[[UIApplication sharedApplication] openURL:mailUrl];
}]];
[alert addAction:
[UIAlertAction actionWithTitle:#"Cancel"
style:UIAlertActionStyleCancel
handler:^(UIAlertAction * _Nonnull action) {
}]];
} else {
[alert addAction:
[UIAlertAction actionWithTitle:#"OK"
style:UIAlertActionStyleCancel
handler:^(UIAlertAction * _Nonnull action) {
}]];
}
[self presentViewController:alert animated:YES completion:nil];
}
Mime Types
If like me, you forgot/are unsure which mimeType to use, here is a resource you can use. Most probably, text/plain is enough, if the file you are attaching is just a plain text, or image/jpeg / image/png for images.
Delegate
As you probably noticed, Xcode throws us a warning on the following line:
mailComposer.mailComposeDelegate = self;
This is because we have not yet set ourself to conform to the appropriate protocol and implement its delegate method. If you want to receive events whether the mail was cancelled, saved, sent or even failed sending, you need to set your class to conform to the protocol MFMailComposeViewControllerDelegate, and handle the following events:
MFMailComposeResultSent
MFMailComposeResultSaved
MFMailComposeResultCancelled
MFMailComposeResultFailed
According to Apple Dev Docs (emphasis mine):
The mail compose view controller is not dismissed automatically. When the user taps the buttons to send the email or cancel the interface, the mail compose view controller calls the mailComposeController:didFinishWithResult:error: method of its delegate. Your implementation of that method must dismiss the view controller explicitly.
With this in mind, we can then implement the delegate method like so:
- (void)mailComposeController:(MFMailComposeViewController *)controller
didFinishWithResult:(MFMailComposeResult)result
error:(NSError *)error
{
switch (result) {
case MFMailComposeResultSent:
// Mail was sent
break;
case MFMailComposeResultSaved:
// Mail was saved as draft
break;
case MFMailComposeResultCancelled:
// Mail composition was cancelled
break;
case MFMailComposeResultFailed:
//
break;
default:
//
break;
}
// Dismiss the mail compose view controller.
[controller dismissViewControllerAnimated:YES completion:nil];
}
Conclusion
The final code may look like so:
- (void)openMailComposerWithSubject:(NSString *)subject
toRecipientArray:(NSArray *)toRecipientArray
ccRecipientArray:(NSArray *)ccRecipientArray
messageBody:(NSString *)messageBody
isMessageBodyHTML:(BOOL)isHTML
attachingFileOnPath:(NSString)filePath
mimeType:(NSString *)mimeType
{
if (![MFMailComposeViewController canSendMail]) {
[self openCannotSendMailDialog];
return;
}
MFMailComposeViewController *mailComposer =
[[MFMailComposeViewController alloc] init];
mailComposer.mailComposeDelegate = self;
mailComposer.subject = subject;
mailComposer.toRecipients = toRecipientArray;
mailComposer.ccRecipients = ccRecipientArray;
[mailComposer setMessageBody:messageBody isHTML:isHTML];
NSData *fileData = [NSData dataWithContentsOfFile:filePath];
NSString *fileName = filePath.lastPathComponent;
[mailComposer addAttachmentData:fileData
mimeType:mimeType
fileName:fileName];
[self presentViewController:mailComposer animated:YES completion:nil];
}
- (void)openCannotSendMailDialog
{
UIAlertController *alert =
[UIAlertController alertControllerWithTitle:#"Error"
message:#"Cannot send mail."
preferredStyle:UIAlertControllerStyleAlert];
NSURL *mailUrl = [NSURL URLWithString:#"message://"];
if ([[UIApplication sharedApplication] canOpenURL:mailUrl]) {
[alert addAction:
[UIAlertAction actionWithTitle:#"Open Mail"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * _Nonnull action) {
[[UIApplication sharedApplication] openURL:mailUrl];
}]];
[alert addAction:
[UIAlertAction actionWithTitle:#"Cancel"
style:UIAlertActionStyleCancel
handler:^(UIAlertAction * _Nonnull action) {
}]];
} else {
[alert addAction:
[UIAlertAction actionWithTitle:#"OK"
style:UIAlertActionStyleCancel
handler:^(UIAlertAction * _Nonnull action) {
}]];
}
[self presentViewController:alert animated:YES completion:nil];
}
- (void)mailComposeController:(MFMailComposeViewController *)controller
didFinishWithResult:(MFMailComposeResult)result
error:(NSError *)error
{
NSString *message;
switch (result) {
case MFMailComposeResultSent:
message = #"Mail was sent.";
break;
case MFMailComposeResultSaved:
message = #"Mail was saved as draft.";
break;
case MFMailComposeResultCancelled:
message = #"Mail composition was cancelled.";
break;
case MFMailComposeResultFailed:
message = #"Mail sending failed.";
break;
default:
//
break;
}
// Dismiss the mail compose view controller.
[controller dismissViewControllerAnimated:YES completion:^{
if (message) {
UIAlertController *alert =
[UIAlertController alertControllerWithTitle:#"Confirmation"
message:message
preferredStyle:UIAlertControllerStyleAlert];
[alert addAction:
[UIAlertAction actionWithTitle:#"OK"
style:UIAlertActionStyleCancel
handler:^(UIAlertAction * _Nonnull action) {
}]];
[self presentViewController:alert animated:YES completion:nil];
}
}];
}
With the button action looking like:
- (IBAction)mailButtonTapped:(id)sender
{
NSString *reportFilePath = ...
[self openMailComposerWithSubject:#"Report Files"
toRecipientArray:mainReportRecipientArray
ccRecipientArray:subReportRecipientArray
messageBody:#"I have attached report files in this email"
isMessageBodyHTML:NO
attachingFileOnPath:reportFilePath
mimeType:#"text/plain"];
}
I kind of went overboard here, but you can, with a grain of salt, take and use the code I posted here. Of course there is a need to adapt it to your requirements, but that is up to you. (I also modified this answer from my working source code, so there might be errors somewhere, please do comment if you find one :))
The issue was that I wasn't looking in the proper place for the file. Thanks #EmilioPalesz .
Here's the code I needed:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory , NSUserDomainMask, YES);
NSString *documentsDir = [paths objectAtIndex:0];
NSString *root = [documentsDir stringByAppendingPathComponent:#"expenses.csv"]
NSData *myData = [NSData dataWithContentsOfFile:root];

How can i use the getter/setter of a Call-Method from Example Code in MailComposer

i have a question regarding the call-methods handling in object-c.
I downloaded the apple sample code for the mail composer (http://developer.apple.com/iphone/library/samplecode/MailComposer/Introduction/Intro.html).
When the user touches the "Compose Mail"-Button in the sample-code the Methode
-(void)displayComposerSheet
{
NSLog(#"MCVC displayComposerSheet");
MFMailComposeViewController *picker = [[MFMailComposeViewController alloc] init];
picker.mailComposeDelegate = self;
[picker setSubject:#"Hello from California!"];
// Set up recipients
NSArray *toRecipients = [NSArray arrayWithObject:#"first#example.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:#"png"];
NSData *myData = [NSData dataWithContentsOfFile:path];
[picker addAttachmentData:myData mimeType:#"image/png" fileName:#"rainy"];
// Fill out the email body text
NSString *emailBody = #"It is raining in sunny California!";
[picker setMessageBody:emailBody isHTML:NO];
[self presentModalViewController:picker animated:YES];
[picker release];
}
will be loaded and the mailcomposerview appears.
After the user sends the mail or cancels it the following methode will be called
- (void)mailComposeController:(MFMailComposeViewController*)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error
{
NSLog(#"MCVC mailComposeController");
message.hidden = NO;
// Notifies users about errors associated with the interface
switch (result)
{
case MFMailComposeResultCancelled:
message.text = #"Result: canceled";
break;
case MFMailComposeResultSaved:
message.text = #"Result: saved";
break;
case MFMailComposeResultSent:
message.text = #"Result: sent";
break;
case MFMailComposeResultFailed:
message.text = #"Result: failed";
break;
default:
message.text = #"Result: not sent";
break;
}
[self dismissModalViewControllerAnimated:YES];
}
in which you can implement your code.
My Question now is how can i get for example the data of "toRecipients", "ccRecipients", "setMessageBody", "setSubject" etc.?
Is this even possible? I dont know how to use the getter in the "- (void)mailComposeController:(MFMailComposeViewController*)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error"-Methode
If i forgot any informations you need i will post them :)
Thanks for everyone who can help me out :)
From the Apple API:
Important: The mail composition interface itself is not customizable and must not be modified by your application. In addition, after presenting the interface, your application is not allowed to make further changes to the email content. The user may still edit the content using the interface, but programmatic changes are ignored. Thus, you must set the values of content fields before presenting the interface.
Looking at this, and also trying out various names that would be appropriate for the ivars in the didFinishWithResult: method, it seems it is NOT possible to get this information from the prebuilt MFMailComposeViewController
you could subclass this class or roll your own to get the functionality..but that seems to be the only way to do it.