MFMailComposeViewController - Unable to presentViewController - ios

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

Related

Cannot Close Game Center Leaderboards Page

I can load up leaderboards with no problem. But I can't get it to close when the "Done" button is clicked.
How I'm opening it:
- (IBAction)leaderboardsClicked:(id)sender{
if ([GKLocalPlayer localPlayer].isAuthenticated) {
GKGameCenterViewController *leaderboardController = [[GKGameCenterViewController alloc] init];
[self presentViewController:leaderboardController animated:YES completion:NULL];
}else{
UIAlertView *alert = [[UIAlertView alloc]initWithTitle: #"Error"
message: #"You must be logged into Game Center to view the leaderboards. Open Game Center?"
delegate: self
cancelButtonTitle:#"No"
otherButtonTitles:#"Yes",nil];
[alert show];
}
}
How I'm closing it:
- (void)gameCenterViewControllerDidFinish:(GKGameCenterViewController *)gameCenterViewController{
NSLog(#"test");
[self dismissViewControllerAnimated:YES completion:nil];
}
EDIT:
The method isn't running at all; so "test" doesn't even get printed.
And I added <GKGameCenterControllerDelegate> to my ViewController's protocol.
Try this instead:
- (IBAction)leaderboardsClicked:(id)sender{
if ([GKLocalPlayer localPlayer].isAuthenticated) {
GKGameCenterViewController *leaderboardController = [[GKGameCenterViewController alloc] init];
leaderboardController.gameCenterDelegate = self;
gameCenterController.viewState = GKGameCenterViewControllerStateLeaderboards;
[self presentViewController:leaderboardController animated:YES completion:NULL];
}else{
UIAlertView *alert = [[UIAlertView alloc]initWithTitle: #"Error"
message: #"You must be logged into Game Center to view the leaderboards. Open Game Center?"
delegate: self
cancelButtonTitle:#"No"
otherButtonTitles:#"Yes",nil];
[alert show];
}
}
And:
- (void) gameCenterViewControllerDidFinish:(GKGameCenterViewController*) gameCenterViewController {
[self dismissViewControllerAnimated:YES completion:nil];
}

Send e-mail via mail.app from my app on iOS

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:^{}];

MFMailComposeViewController black screen on iPad

I'm using cocos2d-x framework and I need to popup the mail when clicking button.
The code works fine on iphone5 (6.0), ipod touch 5(6.0):
MailSender.h
#interface MailSender : UIViewController <MFMailComposeViewControllerDelegate>
{
UIViewController *currentModalViewController;
}
-(void)sendMail:(const char *)subject receiver:(const char *)receiver;
#end
MailSender.mm
#import "MailSender.h"
#import "../cocos2dx/platform/ios/EAGLView.h"
#implementation MailSender
- (void)sendMail:(const char *)subject receiver:(const char *)receiver
{
if ([MFMailComposeViewController canSendMail])
{
MFMailComposeViewController *mailer = [[MFMailComposeViewController alloc] init];
mailer.mailComposeDelegate = self;
[mailer setSubject:[NSString stringWithUTF8String:subject]];
NSArray *toRecipients = [NSArray arrayWithObject:[NSString stringWithFormat:#"%s", receiver]];
[mailer setToRecipients: toRecipients];
//NSString *emailBody = [NSString stringWithFormat:#"<p>This is a sample posting in iOS. My Score is %s!</p>",score];
NSString *emailBody = #"";
[mailer setMessageBody:emailBody isHTML:YES];
// only for iPad
// mailer.modalPresentationStyle = UIModalPresentationFormSheet;
UIViewController* rootViewController = [UIApplication sharedApplication].keyWindow.rootViewController;
currentModalViewController = [UIViewController alloc];
[rootViewController.view addSubview:currentModalViewController.view];
[currentModalViewController presentViewController:mailer animated:true 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];
[alert release];
}
}
- (void)mailComposeController:(MFMailComposeViewController*)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error
{
const char *message;
switch (result)
{
case MFMailComposeResultCancelled:
message = "Mail cancelled";
break;
case MFMailComposeResultSaved:
message = "Mail saved";
break;
case MFMailComposeResultSent:
message = "Mail send";
break;
case MFMailComposeResultFailed:
message = "Mail failed";
break;
default:
message = "Mail cancelled";
break;
}
NSLog(#"%s",message);
[currentModalViewController dismissViewControllerAnimated:true completion:nil];
[currentModalViewController.view.superview removeFromSuperview];
[currentModalViewController release];
}
#end
But on my ipad mini (6.0) the mail popped up correctly but when clicked the "send mail" or "cancel" the view was removed and leaving a black screen (everything on the screen is gone)
Any advice will be appreciated, thanks :)
try this code
if ([MFMailComposeViewController canSendMail]) {
mailComposer = [[MFMailComposeViewController alloc]init];
mailComposer.mailComposeDelegate = self;
[mailComposer setToRecipients:#[#"yourmail#com"]];
[mailComposer setSubject:#"Subject"];
[mailComposer setMessageBody:#"hello \n" isHTML:NO];
[self presentViewController:mailComposer animated:YES completion:nil];
}
else{
UIAlertView *alert=[[UIAlertView alloc] initWithTitle:#"Error"
message:#"can not send mail with this device"
delegate:nil
cancelButtonTitle:#"Ok"
otherButtonTitles:nil, nil];
[alert show];
}
pragma mark MFMailComposeViewControllerDelegate
-(void)mailComposeController:(MFMailComposeViewController *)controller
didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error{
if (result) {
NSLog(#"Result : %d",result);
}
if (error) {
NSLog(#"Error : %#",error);
}
[self dismissViewControllerAnimated:YES completion:nil];
}
I'm using this code for feedback via email in my cocos2d-x game.
Application::getInstance()->openURL("mailto:" + SUPPORT_EMAIL);
You can add subject:
Application::getInstance()->openURL("mailto:" + SUPPORT_EMAIL + "?subject=Hello from NX");
This solution tested on iOS and Android.

UIImagePickerController - [picker dismissViewControllerAnimated:YES completion:Nil]; Error

I have been trying this for the past 2 days and I am not able to figure out the answer. I have searched all over and I haven't found the answer.
The question is I have a button which brings up the camera in my app(to take photos only). The camera opens up, but when i take a picture and click on "USE"(which is displayed at the bottom right) its crashing. Also, when the camera opens up, before taking a picture when I click "Cancel" it again crashes.
I tried using breakpoints and found out that, When I click on the "USE" button, it crashes in this line
[picker dismissViewControllerAnimated:YES completion:Nil]
I'm testing it in my iPad (iOS6).
Here is the Button Code here :
-(IBAction)getAlbum:(id)sender {
if([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
NSArray *media = [UIImagePickerController
availableMediaTypesForSourceType: UIImagePickerControllerSourceTypeCamera];
if ([media containsObject:(NSString*)kUTTypeImage] == YES) {
UIImagePickerController *picker = [[UIImagePickerController alloc] init];
picker.sourceType = UIImagePickerControllerSourceTypeCamera;
//picker.cameraCaptureMode = UIImagePickerControllerCameraCaptureModePhoto;
[picker setMediaTypes:[NSArray arrayWithObject:(NSString *)kUTTypeImage]];
picker.delegate = self;
//[self presentModalViewController:picker animated:YES]; //Since [Modal](http://stackoverflow.com/questions/12445190/dismissmodalviewcontrolleranimated-deprecated) has been removed
[self presentViewController:picker animated:YES completion:Nil];
//[picker release];
}
else {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Unsupported!"
message:#"Camera does not support photo capturing."
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
[alert release];
}
}
else {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Unavailable!"
message:#"This device does not have a camera."
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
[alert release];
}
}
imagePickerController Method here:
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
NSLog(#"Media Info: %#", info);
NSString *mediaType = [info valueForKey:UIImagePickerControllerMediaType];
if([mediaType isEqualToString:(NSString*)kUTTypeImage]) {
UIImage *photoTaken = [info objectForKey:#"UIImagePickerControllerOriginalImage"];
//Save Photo to library only if it wasnt already saved i.e. its just been taken
if (picker.sourceType == UIImagePickerControllerSourceTypeCamera) {
UIImageWriteToSavedPhotosAlbum(photoTaken, self, #selector(image:didFinishSavingWithError:contextInfo:), nil);
}
selectedLogoImg.image=photoTaken; //selectedLogoImg is the imageView
[self.clipartItemView addSubview:selectedLogoImg]; // To detect touch and move it I place it as a subview of self.clipartItemView
}
//[picker dismissModalViewControllerAnimated:YES];
[picker dismissViewControllerAnimated:YES completion:Nil]
//[picker release];
//[picker dismissViewControllerAnimated:YES completion:^{
// NSLog(#"Dismiss completed");
//}];
}
didFinishSavingWithError Code Here:
- (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo {
UIAlertView *alert;
//NSLog(#"Image:%#", image);
if (error) {
alert = [[UIAlertView alloc] initWithTitle:#"Error!"
message:[error localizedDescription]
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
[alert release];
}
}
imagePickerControllerDidCancel Code Here:
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker {
//[picker dismissModalViewControllerAnimated:YES];
/*[picker dismissViewControllerAnimated:YES completion:^{
[self.view sendSubviewToBack:cardGalleryView];
}];*/
[picker dismissViewControllerAnimated:YES completion:Nil];
}
You should send the dismissViewControllerAnimated:completion: message to the view controller, not the picker. Try:
[self dismissViewControllerAnimated:YES completion:nil];
The above method is only for iOS 6. You need to use [self dismissModalViewControllerAnimated:YES] for iOS 5 and below.
Take a look at the description of the method in the documentation:
Dismisses the view controller that was presented by the receiver.
The presenting view controller is responsible for dismissing the view
controller it presented. If you call this method on the presented view
controller itself, however, it automatically forwards the message to
the presenting view controller
This problem is due to your UIImagePickerController *picker object . ViewController isn't able to identify your picker object reference out of the getAlbum method scope.
1.> you can create UIImagePickerController object in your .h file
#interface yourViewController : UIViewController <UIImagePickerControllerDelegate,UINavigationControllerDelegate,UINavigationControllerDelegate,UIPopoverControllerDelegate>
{
UIImagePickerController *picker;
UIPopoverController *popover;
}
and in .m file you just use it inside getAlbum IBAction method
-(IBAction)getAlbum:(id)sender {
if([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
NSArray *media = [UIImagePickerController
availableMediaTypesForSourceType: UIImagePickerControllerSourceTypeCamera];
if ([media containsObject:(NSString*)kUTTypeImage] == YES) {
UIButton *btn=(UIButton *)sender;
if ([popover isPopoverVisible])
{
[popover dismissPopoverAnimated:YES];
popover=nil;
}
picker = [[UIImagePickerController alloc]init];
picker.sourceType = UIImagePickerControllerSourceTypeCamera;
[picker setMediaTypes:[NSArray arrayWithObject:(NSString *)kUTTypeImage]];
picker.delegate = self;
popover = [[UIPopoverController alloc] initWithContentViewController:picker];
[popover presentPopoverFromRect:CGRectMake(btn.frame.size.width,btn.frame.size.height/2,1,1) inView:self.view permittedArrowDirections:UIPopoverArrowDirectionUp animated:YES];
}
else {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Unsupported!"
message:#"Camera does not support photo capturing."
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
[alert release];
}
}
else {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Unavailable!"
message:#"This device does not have a camera."
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
[alert release];
}
}
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingImage:(UIImage *)myimage editingInfo:(NSDictionary *)editingInfo
{
myimage = [myimage fixOrientation];
[picker dismissModalViewControllerAnimated:YES];
[popover dismissPopoverAnimated:YES];
}
I hope it helps you to better understand.

How to change body of email in MFMailComposeViewController?

I want to put something like order same packet and if I finish my order I want send email; how can I modify this code to change change the body of the email?
inappemailViewController.h
#import <UIKit/UIKit.h>
#import <MessageUI/MFMailComposeViewController.h>
#interface inappemailViewController :
UIViewController <MFMailComposeViewControllerDelegate> {
}
-(IBAction)email;
#end
inappemailViewController.m
-(IBAction)email {
MFMailComposeViewController *composer = [[MFMailComposeViewController alloc] init];
[composer setMailComposeDelegate:self];
if ([MFMailComposeViewController canSendMail]) {
[composer setToRecipients:[NSArray arrayWithObjects:#"123#abc.com", nil]];
[composer setSubject:#"subject here"];
[composer setMessageBody:#"message here" isHTML:NO];
[composer setModalTransitionStyle:UIModalTransitionStyleCrossDissolve];
[self presentModalViewController:composer animated:YES];
[composer release];
}
else
[composer release];
}
-(void)mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error {
if (error) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"error"
message:[NSString stringWithFormat:#"error %#", [error description]]
delegate:nil cancelButtonTitle:#"dismiss" otherButtonTitles:nil, nil];
[alert show];
[alert release];
[self dismissModalViewControllerAnimated:YES];
}
else {
[self dismissModalViewControllerAnimated:YES];
}
}
The message body is set on this line:
       
[composer setMessageBody:#"message here" isHTML:NO];
So just change "message here" to whatever you want the email to say. You could also make it be an NSString object that you set elsewhere.
You can fix this code. Your message body is set on this line:
[composer setMessageBody:#"message here" isHTML:NO];
Hope this helps.

Resources