Getting a SIGABRT error in dismissModalViewController - objective-c

Im receiving a SIGABRT error when I cancel a MFMailComposeViewController, exactly in the dismissViewController, don't work
I have a UIViewController within a UINavigationController.
My Code:
- (void)sendMail {
if ([MFMailComposeViewController canSendMail]) {
controller = [[MFMailComposeViewController alloc] init];
[[controller navigationBar] setTintColor:[UIColor getHexColorWithRGB:#"e2de09" alpha:1.0f]];
controller.mailComposeDelegate = self;
[controller setSubject:#"Subject"];
NSString *msg="xxxxx";
[controller setMessageBody:msg isHTML:YES];
[self presentModalViewController:controller animated:YES];
} else {
NSString * errorString = [NSString stringWithFormat:#"mail account not set."];
UIAlertView * errorAlert = [[UIAlertView alloc] initWithTitle:#"Error:" message:errorString delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[errorAlert show];
}
}
The presentModalViewController:animated: works correctly.
- (void)mailComposeController:(MFMailComposeViewController*)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error {
[self becomeFirstResponder];
[self dismissModalViewControllerAnimated:YES];
}
But calling [self dissmissModalViewControllerAnimatedLYES] causes a SIGABRT error.

I think the "dismissModalViewControllerAnimated" should be called on the MFMailComposer object, in your case "controller". Note that it is in fact a view controller.

It's resolved!
I had a viewWillDisappear: method where I was removing views...
This method was being called before of present the ModalView and my ViewController was over released on dissmissModalViewController.
I have changed this method.
Thanks

Related

MFMessageComposeViewController - Getting stuck after sending SMS in ios7

After sending SMS from my phone(it's working properly) in my project using the MFMessageComposeViewController I can't get back to the app or press cancel. Instead I'm stuck in Apple SMS interface and I can't do anything else then to restart the app. Do I miss something in didFinishWithResult or could it be something else? Thanks
- (IBAction)sendSMS:(id)sender {
MFMessageComposeViewController *controller =
[[[MFMessageComposeViewController alloc] init] autorelease];
if([MFMessageComposeViewController canSendText])
{
NSString *str= #"Hi";
controller.body = str;
controller.recipients = [NSArray arrayWithObjects:
#"", nil];
controller.delegate = self;
[self dismissViewControllerAnimated:YES
completion:nil];
[self presentViewController:controller animated:YES completion:nil];
}
}
- (void)messageComposeViewController:(MFMessageComposeViewController *)controller didFinishWithResult:(MessageComposeResult) result
{
switch (result) {
case MessageComposeResultCancelled:
break;
case MessageComposeResultFailed:
{
UIAlertView *warningAlert = [[UIAlertView alloc] initWithTitle:#"Error" message:#"Failed to send SMS!" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[warningAlert show];
break;
}
case MessageComposeResultSent:
break;
default:
break;
}
[self dismissViewControllerAnimated:YES completion:nil];
}

MFMailComposer Dismissing immediately after launch

I am trying to launch the MFMailComposer on the iOS 7 simulator and as soon as it comes up it immediately dissmises itself and I get the following error in the debugger.
_serviceViewControllerReady:error: Error Domain=NSCocoaErrorDomain Code=4097 "The operation couldn’t be completed. (Cocoa error 4097.)"
Here is my code
-(void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
switch (buttonIndex) {
case 0:
break;
case 1:{
if ([MFMailComposeViewController canSendMail]) {
MFMailComposeViewController *mailViewController = [[MFMailComposeViewController alloc] init];
mailViewController.mailComposeDelegate = self;
[mailViewController setSubject:[NSString stringWithFormat:#"%# Totals Report",_teamStats.relationshipTeam.teamName]];
[mailViewController setMessageBody:#"\n\n\n\n\nSent From HoopMetrics" isHTML:NO];
// Attach a doc to the email
NSData* data = [_teamStats.relationshipTeam pdfDataFromString:_teamStats.teamTotalsAsString];
[mailViewController addAttachmentData:data mimeType:#"application/pdf" fileName:#"Totals Report"];
[self presentViewController:mailViewController animated:YES completion:nil];
}
else{
HMAlertView*alert = [[HMAlertView alloc]initWithTitle:#"No Email" message:#"Please, set up an email account on your device" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
[alert show];
}
}
break;
}
I faced the same problem. Just turn off appearance customization for UINavigationBar or UIBarButtonItem or some another element that MFMailComposeViewController may use.
You can get around this with the following hack using performSelector:
- (IBAction)sendEmail:(id)sender {
[self performSelector:#selector(showEmailComposer) withObject:nil afterDelay:0.0];
}
-(void) showEmailComposer{
MFMailComposeViewController *mailViewController = [[MFMailComposeViewController alloc] init];
//Set recipients...other stuff
[mailViewController setToRecipients:recipients];
[mailViewController setSubject:subject];
[mailViewController setMessageBody:body isHTML:isHTML];
mailViewController.title = #"Email VC Title";
mailViewController.mailComposeDelegate = delegate;
[self presentViewController:mailViewController
animated:YES
completion:NULL];
}

unable to load the mail client in iOS

I noticed that I am using the mail functionality several time so I decided to make an independent Class for functions that get repeated several time instead of copy-pasting the code several times
the class get successfully called and the e-mail function get successfully called as well but the e-mail client of the phone does not appear after the function is called
here is my code
in the main class I do the following call
-(void)emailFunction{
...
CommonlyUsed Email = [[CommonlyUsed alloc] init];
[Email sendMail:receipient :CC :BCC :subject :body];
...
}
in my CommonlyUsed.h I have the following IDEs called :
#import <UIKit/UIKit.h>
#import <MessageUI/MFMailComposeViewController.h>
#import <MessageUI/MessageUI.h>
#interface CommonlyUsed : UIViewController <MFMailComposeViewControllerDelegate>{
in CommonlyUsed.m I have the following :
-(void)sendMail:(NSString*)receipient:(NSString*)cc:(NSString*)bcc:(NSString*)subject:(NSString*)body{
MFMailComposeViewController *composer = [[MFMailComposeViewController alloc] init];
[ composer setMailComposeDelegate:self];
if ( [MFMailComposeViewController canSendMail]){
if (receipient) {
[composer setToRecipients:[NSArray arrayWithObjects:receipient, nil]];
}
if (cc) {
[composer setCcRecipients:[NSArray arrayWithObjects:receipient, nil]];
}
if (bcc) {
[composer setBccRecipients:[NSArray arrayWithObjects:receipient, nil]];
}
if (subject) {
[composer setSubject:subject];
}
[composer setMessageBody:body isHTML:HTMLBody];
[composer setModalTransitionStyle:UIModalTransitionStyleCrossDissolve];
[self presentModalViewController:composer animated:YES];
}
}
- (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];
[self dismissModalViewControllerAnimated:YES];
}
else{
[self dismissModalViewControllerAnimated:YES];
}
}
the code compiles and runs without errors what am I missing ??
Instead of doing this:
[self presentModalViewController:composer animated:YES];
do this:
[[[[[UIApplication sharedApplication] delegate] window] rootViewController] presentModalViewController:composer animated:YES];
or this:
[[[[UIApplication sharedApplication] keyWindow] rootViewController] presentModalViewController:composer animated:YES];
Your class Email is not currently an active view controller so it can't present a modal view controller, you need to use an active one, like the rootViewController of the main UIWindow.
EDIT:
If your using ARC by the time the emailClient gets dismissed your object(delegate) would have been removed from memory, so a solution is to make the CommonlyUsed class a Singleton:
+(CommonlyUsed *)sharedInstance {
static CommonlyUsed * cu = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
cu = [[CommonlyUsed alloc] init];
});
return cu;
}
So you would use it this way:
CommonlyUsed * email = [CommonlyUsed sharedInstance];
[email sendMail:receipient :CC :BCC :subject :body];
You send presentModalViewController: to your instance Email of class CommonlyUsed, but this instance is not a view controller in the view hierarchy.
You must send presentModalViewController: to your currently active view controller.

iOS Mail Composer Won't Dismiss

I am trying to take a screenshot and email it using the mail composer. Everything works great except the mail composer won't dismiss. This post seems to have the same problem, but the solution provided did not work for me. Can't dismiss the email composer view in iPhone?
- (IBAction)Email:(id)sender {
UIGraphicsBeginImageContext(self.view.frame.size);
[self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage * image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
NSData * imageData = UIImageJPEGRepresentation(image, 1.0);
if ( [MFMailComposeViewController canSendMail] ) {
MFMailComposeViewController * mailComposer = [[[MFMailComposeViewController alloc] init] autorelease];
mailComposer.delegate = self;
[mailComposer setSubject:#"Risk Assessment"];
[mailComposer addAttachmentData:imageData mimeType:#"image/jpeg" fileName:#"attachment.jpg"];
[self presentModalViewController:mailComposer animated:YES];
}
}
The above code works great. How do I call this bottom portion. It seems like the compiler just skips past it.
-(void)mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error{
if (error){
NSString *errorTitle = #"Mail Error";
NSString *errorDescription = [error localizedDescription];
UIAlertView *errorView = [[UIAlertView alloc]initWithTitle:errorTitle message:errorDescription delegate:self cancelButtonTitle:nil otherButtonTitles:#"OK", nil];
[errorView show];
[errorView release];
}
[controller dismissModalViewControllerAnimated:YES];
}
Thanks in advance.
Try
mailComposer.mailComposeDelegate = self;
instead of
mailComposer.delegate = self;
From the MFMailComposeViewController documentation:
#property(nonatomic,assign) id<MFMailComposeViewControllerDelegate> mailComposeDelegate;
The delegate object is responsible for dismissing the view presented by this view controller at the appropriate time. Therefore, you should always provide a delegate and that object should implement the methods of the MFMailComposeViewControllerDelegate protocol.
I am pretty sure that last line should be
[self dismissModalViewControllerAnimated:YES];
The ViewController that presented the view modally, also dismisses it.

Photo Library view stays on screen after choosing an image with UIImagePickerController

After I choose a picture through the UIImagePickerController interface from the Photo Library, the Photo Library view stays displayed, even though I've called dismissModelViewControllerAnimated in imagePickerController:didFinishPickingImage:editingInfo.
Has anyone seen this? These are the three relevant methods I'm using:
- (IBAction)choosePictureFromLibrary:(id)sender {
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary]) {
UIImagePickerController* picker = [[UIImagePickerController alloc] init];
picker.delegate = self;
picker.allowsImageEditing = YES;
picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
[self presentModalViewController:picker animated:YES];
[picker release];
}
else {
UIAlertView* alert = [[UIAlertView alloc] initWithTitle:#"Error accessing Photo Library" message:#"This device does not support a Photo Library." delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
[alert release];
}
}
- (void)imagePickerController:(UIImagePickerController*)picker didFinishPickingImage:(UIImage*)image editingInfo:(NSDictionary*)editingInfo {
UIAlertView* alert = [[UIAlertView alloc] initWithTitle:#"Picture picked!" message:#"You picked a picture!" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
[alert release];
[picker dismissModalViewControllerAnimated:YES];
}
- (void)imagePickerControllerDidCancel:(UIImagePickerController*)picker {
[picker dismissModalViewControllerAnimated:YES];
}
I would have thought that calling imagePickerController:didFinishPickingImage:editingInfo would completely dismiss the Photo Library view, but it doesn't seem to. Is there anything else I have to do to make it go away?
You need to access the viewController of the picker not the picker itself. Try this line instead.
[[picker parentViewController] dismissModalViewControllerAnimated:YES];
You can just call
[self dismissModalViewControllerAnimated:YES];
to dismiss any modal view controller on top of the current view.
This makes sense since you present the view controller by calling:
[self presentModalViewController:picker animated:YES];
Just an update to the answers to this
[self dismissModalViewControllerAnimated:YES];
has been deprecated in iOS 6.0 so you now need to use.
[self dismissViewControllerAnimated:YES completion:nil];
Not a huge change but for anyone that looks at this question and they are using iOS 6.0 they will need an updated answer.
[self presentModalViewController:filePicker animated:YES];
has also been deprecated in favor of
[self presentViewController:filePicker animated:YES completion:nil];