I'm trying to use the MFMessageComposer to pre-fill sms for the user. I am trying use a variable that is stored in a mutable array and use that number to pre-fill the phone number. However it doesn't work with the code below at the recipient part. I've tried changing it to a string, adding it to the array. The phone just doesn't do anything.
However if I do a manual number using #[#"123132131235"]; for the recipients it would work.
- (IBAction)smsSend:(id)sender {
{
MFMessageComposeViewController *controller = [[MFMessageComposeViewController alloc] init];
[controller setMessageComposeDelegate:self];
if([MFMessageComposeViewController canSendText])
{
controller.recipients = [[NSArray alloc] initWithObjects:[Detail valueForKey:#"Phone"], nil];
NSLog(#"%#",[Detail valueForKey:#"Phone"]);
controller.body = #"Hello testing";
[self presentViewController:controller animated:YES completion:NULL];
} else {
NSLog(#"cannot send");
}
}
}
Please help me.
Cheers,
Tony.
Try this:
- (IBAction)smsSend:(id)sender
{
{
MFMessageComposeViewController *controller = [[MFMessageComposeViewController alloc] init];
[controller setMessageComposeDelegate:self];
if([MFMessageComposeViewController canSendText])
{
controller.recipients = [NSArray arrayWithObjects:[Detail valueForKey:#"Phone"], nil];
controller.body = #"Hello testing";
[self presentViewController:controller animated:YES completion:NULL];
}
else
{
NSLog(#"cannot send");
}
}
}
The only change I have made is recipient array allocation. Recipient array is not the array that you own so instead of [NSArray alloc] you should directly initialise array with objects.
initWithObject returns an array with a retain count of 1, i.e. you own the array and you must release it at some point to prevent memory leaks.
arrayWithObject returns an autoreleased array so you do not have to worry about releasing it when you don't need it anymore (but if you store it in an instance variable, you should retain it to prevent the autorelease pool from freeing it)
Related
So basically I want to share the content only through mail and I do not want to show the option of message. Could you help me out with that. Also I want to set the subject of the email through the code and also the recipient of the email through the code
You can put this in the method for a button tap or something like that.
if ([MFMailComposeViewController canSendMail]) {
MFMailComposeViewController *mailViewController = [[MFMailComposeViewController alloc] init];
mailViewController.mailComposeDelegate = controller;
[mailViewController setSubject:subject];
NSMutableArray *emails = [[NSMutableArray alloc] init];
[emails addObject:address];
[mailViewController setToRecipients:emails];
mailViewController.navigationBar.translucent = NO;
mailViewController.navigationBar.tintColor = [UIColor whiteColor];
mailViewController.navigationBar.titleTextAttributes = #{NSForegroundColorAttributeName : [UIColor whiteColor]};
[controller presentViewController:mailViewController animated:YES completion:^{
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent animated:NO];
}];
}
In my app, I have a tableView whose material is from my NSmutableDictionary. When I push a button, I want to send these material to a email.Here is the code for sending email:
//Below to send email
- (IBAction)showEmail:(id)sender {
// Email Subject
NSString *emailTitle = #"Course Planner of iBcChem";
// Email Content
NSString *messageBody = #"Please check my course plan";
// To address
NSArray *toRecipents = [NSArray arrayWithObject:#"xxxxx#gmail.com"];
MFMailComposeViewController *mc = [[MFMailComposeViewController alloc] init];
mc.mailComposeDelegate = self;
[mc setSubject:emailTitle];
[mc setMessageBody:messageBody isHTML:NO];//want to fix here
[mc setToRecipients:toRecipents];
// Present mail view controller on screen
[self presentViewController:mc animated:YES completion:NULL];
}
Here is my question:
How can I add my material to the messageBody please? Can I use the method similar to show my dictionary like below in my messageBody please?
NSLog(#"Dictionary: %#", [_sectionContents description]);//test dictionary here
Where _sectionContents is my dictionary.
You can attach you dictionary by the same code which you have written.
Here is the code for you.
NSString *emailTitle = #"Course Planner of iBcChem";
NSString *messageBody = #"Please check my course plan";
NSDictionary *dci = [[NSDictionary alloc] initWithObjects:[NSArray arrayWithObjects:#"1",#"2", nil] forKeys:[NSArray arrayWithObjects:#"A",#"B", nil]];
NSArray *toRecipents = [NSArray arrayWithObject:#"xxxxx#gmail.com"];
MFMailComposeViewController *mc = [[MFMailComposeViewController alloc] init];
mc.mailComposeDelegate = self;
[mc setSubject:emailTitle];
[mc setMessageBody:dci.description isHTML:NO];
[mc setToRecipients:toRecipents];
[self presentViewController:mc animated:YES completion:NULL];
In simulator mail delegate will take some time to load the Body part of mailcomposersheet. The body will look like.
{
A = 1;
B = 2;
}
Enjoy Coding !!
I'm using the MFMessageComposeViewController to allow my users to send out app download invites to their friends. I want to load the View Controller with the recipients field blank, so the user can add whoever they wish. When I use the code below, a recipient 'Buddy Name' displays. How can I remove this?
MFMessageComposeViewController *messageController = [[MFMessageComposeViewController alloc] init];
if ([MFMessageComposeViewController canSendText])
{
messageController.body = #"My app text...";
messageController.recipients = [NSArray arrayWithObjects:#"", nil];
messageController.messageComposeDelegate = self;
[self presentViewController:messageController animated:YES completion:nil];
}
This can remove the Buddy Name:
messageController.recipients = nil
Just remove the following line
messageController.recipients = [NSArray arrayWithObjects:#"", nil];
I'm trying to send mail to list of email array that I receive from database, when I send the recipient list gets populated in iOS 7 but when I tried in iOS 5 the recipient list doesn't get populated. Any Idea why? This is my mail function
-(void)sendEmailToContacts:(NSArray *)fList withText:(NSString *)emailText withTag:(NSInteger )tag
{
if([MFMailComposeViewController canSendMail])
{
MFMailComposeViewController *mailComposer = [[MFMailComposeViewController alloc] init];
mailComposer.view.tag=tag;
NSString *htmlBody =[NSString stringWithFormat:#"%#",_currentAdd.contentUrl,addtext];
[mailComposer setMessageBody:htmlBody isHTML:YES];
[mailComposer setSubject:_currentMail.subject];
mailComposer.mailComposeDelegate = self;
[mailComposer setToRecipients:fList];
[self presentViewController:mailComposer animated:YES completion:nil];
}
else
{
NSLog(#"Device is unable to send email in its current state.");
}
}
My fList (recipient list) is an NSArray, this is a sample output of my fList
(
"john#gmail.com",
"mary#gmail.com",
"akhil#gmail.com",
"tester#gmail.com"
)
Recipients are expected as immutable array. check your array type
NSArray *usersTo = [NSArray arrayWithObject: #"raja#apple.com"];
[mailComposer setToRecipients:usersTo];
Try this one.
NSArray *fList = [NSArray arrayWithObjects:#"raja#apple.com",#"john#gmail.com",#"mary#gmail.com",#"akhil#gmail.com",#"tester#gmail.com", nil];
MFMailComposeViewController *mailComposer = [[MFMailComposeViewController alloc] init];
mailComposer.view.tag=tag;
NSString *htmlBody =[NSString stringWithFormat:#"%#",_currentAdd.contentUrl,addtext];
[mailComposer setMessageBody:htmlBody isHTML:YES];
mailComposer.mailComposeDelegate = self;
[mailComposer setSubject:_currentMail.subject];
mailComposer.delegate = self;
[mailComposer setToRecipients:fList];
[self presentViewController:mailComposer animated:YES completion:nil];
-(void)sendEmailToContacts:(NSArray *)fList withText:(NSString *)emailText withTag:(NSInteger )tag
{
if([MFMailComposeViewController canSendMail])
{
MFMailComposeViewController *mailComposer = [[MFMailComposeViewController alloc] init];
//mailComposer.view.tag=tag;
NSString *htmlBody =[NSString stringWithFormat:#"%#",_currentAdd.contentUrl,addtext];
[mailComposer setMessageBody:htmlBody isHTML:YES];
[mailComposer setSubject:_currentMail.subject];
mailComposer.mailComposeDelegate = self;
[mailComposer setToRecipients:fList];
[self presentViewController:mailComposer animated:YES completion:nil];
}
else
{
NSLog(#"Device is unable to send email in its current state.");
}
}
Apparently the issue was with setting tag if I try to set the tag before setToRecipients line it will not show the recipients list in iOS 5, it will work if the setting tag line is commented out or set after setToRecipients.
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:...];