Problem MFMessageComposerViewController in iPhone sdk - iphone

I am trying to implement a SMS application. In that when I tried to send my sms I got an exception at [self.navigationController presentModalViewController:picker animated:YES];. I am very new to this. Can you guys please help me?. My code is as follows.
MFMessageComposeViewController *picker = [[MFMessageComposeViewController alloc] init];
picker.delegate = self;
picker.recipients = [NSArray arrayWithObject:#"123456789"]; // your recipient number or self for testing
picker.body = #"test from OS4";
[self.navigationController presentModalViewController:picker animated:YES];
[picker release];
My Log message is as follows,
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Application tried to present a nil modal view controller on target <UINavigationController: 0x5b2c120>.
Thanks in Advance,
S.

The message means picker is nil, i.e. the MFMessageComposeViewController is not created successfully.
Make sure [MFMessageComposeViewController canSendText] returns YES, i.e..
if (![MFMessageComposeViewController canSendText]) {
// show message box for user that SMS cannot be sent
} else {
MFMessageComposeViewController* picker = ...;
...
}

Most probably you are testing this in your iPhone simulator, MFMessageComposeViewController does not work on a simulator and returns nil

Three things come to mind.
First, have you declared your view controller class to be implement MFMailComposeViewControllerDelegate? And have you defined mailComposeController:didFinishWithResult:error: ?
Second, you could just have: [self presentModalViewController:picker animated:YES];
Third, are you sure that picker is non-nil?

The main reason that the modal view will throw a nil exception usually has to do with the device under test not having an email account configured in settings (hence the other comment about the modal view not working in the simulator). #KennyTM's answer is a great way to handle this. Just popup an alert dialog notifying the user.

Related

'Application tried to present a nil modal view controller on target' error/crash when trying to open mail composer

I have a simple app, which opens a modal view to send email. Am using Xcode 4.2 and iOS 5, and am testing with iOS Simulator. The app crashes with
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason:
'Application tried to present a nil modal view controller on target
.'
when executing the line:
[self presentModalViewController:mailComposer animated:YES];
though I have initialized the object 'mailComposer'.
Class com_FirstViewController.m :
#import "com_FirstViewController.h"
...
#implementation com_FirstViewController
....
....
-(void)showEmailComposer {
Class mailClass = (NSClassFromString(#"MFMailComposeViewController"));
if (mailClass != nil)
{
if ([mailClass canSendMail]) {
NSLog(#"showEmailComposer: Calling displayComposerSheet");
[self displayComposerSheet];
} else {
NSLog(#"showEmailComposer: Calling launchMailAppOnDevice");
[self launchMailAppOnDevice];
}
}
else {
NSLog(#"showEmailComposer: Calling launchMailAppOnDevice");
[self launchMailAppOnDevice];
}
}
#pragma mark -
#pragma mark Compose Mail
-(void) displayComposerSheet {
mailComposer = [[MFMessageComposeViewController alloc] init];
mailComposer.messageComposeDelegate = self;
// Set the mail title
[mailComposer setTitle:#"Mail Title"];
// Set the recipients
NSArray *toRecipients = [NSArray arrayWithObject:#"user#company.com"];
[mailComposer setRecipients:toRecipients];
// EMail Body
NSString *mailBody = #"This is the mail body";
[mailComposer setBody:mailBody];
NSLog(#"present the modal view ctlr");
[self presentModalViewController:mailComposer animated:YES];
}
...
...
Any pointers please?
I have also encountered a similar problem. I allocated an instance of MFMailComposeViewController and tried to present it modally. I also got an exception:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Application tried to present a nil modal view controller on target
This was because the Mail option was disabled in the settings of the iPhone. It can be the case also when no mail account is set up in the device. So the MFMailCompseViewController instance will be nil and presenting it modally will cause the crash.
I used the canSendMail method of the MFMailComposeViewController to get around this issue.
Class mailClass = (NSClassFromString(#"MFMailComposeViewController"));
if (mailClass != nil) {
MFMailComposeViewController * mailView = [[MFMailComposeViewController alloc] init];
mailView.mailComposeDelegate = self;
//Set the subject
[mailView setSubject:emailSubject];
//Set the mail body
[mailView setMessageBody:emailBody isHTML:YES];
//Display Email Composer
if([mailClass canSendMail]) {
[self.navControl presentModalViewController:mailView animated:YES];
}
}
mailComposer = [[MFMessageComposeViewController alloc] init];
is the source of the problem, in my opinion. There's no way the simulator can send SMS messages, so the initializer method may return NULL. Anyways, sou seem to be wanting to send an email, so I'd say you need to use
mailComposer = [[MFMailComposeViewController alloc] init];

iPhone - Objective C - PLCameraPreviewView class

My app uses camera to take a photo.
When I open the camera the second time (after I opened it the first time and closed it),
the app crashes with this message:
*** -[PLCameraPreviewView isKindOfClass:]: message sent to deallocated instance 0x4193380
what is PLCameraPreviewView?
do you know what is happening, I just use the following code to open the camera:
self.imagePicker = [[[UIImagePickerController alloc] init] autorelease];
imagePicker.delegate = self;
imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;
imagePicker.allowsEditing = NO;
[self presentModalViewController:imagePicker animated:YES];
The reason is that I have a UIView category which has a method:
+(UIView*)firstResponder;
when I change the name of this method to
+(UIView*)theFirstResponder;
the problem went away.
I guess we should not name the methods in our category similar to the built-in method names of that class.

Mail comes Without Message content using MFMailComposeViewController in iPhone

I have faced some problems, when the user sent the mail. Some of the time the mail comes without message content(Email body), even the user typed the message content.The message content doesn't displayed only some times.(For 10 mail comes into my inbox, 2 or 3 messages comes without content in the email body) So please guide me why its happening?
Here my code is,
- (void)viewDidLoad {
[self displayComposerSheet];
}
-(void) displayComposerSheet
{
picker = [[MFMailComposeViewController alloc] init];
picker.mailComposeDelegate = self;
if ([MFMailComposeViewController canSendMail]) {
[picker setToRecipients:[NSArray arrayWithObjects:#"aaa#bbb.com",nil]];
[picker setSubject:#"ShoutOuts"];
}
[self presentModalViewController:picker animated:YES];
}
Please Help me Out.
Thanks!
I don't have a straight answer, but two hints:
a) Why are you calling displayComposerSheet in viewDidLoad? I'd rather put it into viewWillAppear, since the view controller might already be loaded and in memory if used once again.
b) Did you try pre-filling the mail body with a placeholder text to see if that is being sent?

MFMessageComposeViewController alloc returns nil

In my application, MFMailComposeViewController works fine but creating a new instance of MFMessageComposeViewController fails.
Here is the code for both:
-( IBAction)sendSMS: (id)sender
{
MFMessageComposeViewController *picker = [[[MFMessageComposeViewController alloc] init] autorelease];
picker.messageComposeDelegate = self;
NSArray *toRecipients = [NSArray arrayWithObject: cell.currentTitle ];
picker.recipients = toRecipients;
[self presentModalViewController:picker animated:YES];
}
-( IBAction)sendEmail: (id)sender
{
MFMailComposeViewController *picker = [[[MFMailComposeViewController alloc] init] autorelease];
picker.mailComposeDelegate = self;
NSArray *toRecipients = [NSArray arrayWithObject: email.currentTitle ];
[picker setToRecipients:toRecipients];
[self presentModalViewController:picker animated:YES];
}
Its seemingly obvious that everything is linking correctly because the email view controller works fine. Is there something I am missing maybe configuration wise?
Have you checked +[MFMessageComposeViewController canSendText]?
From the MFMessageComposeViewController Class Reference,
Before presenting a message composition view, call the canSendText class method to ensure that the user’s device is appropriately configured. Do not attempt to present a message composition view if the canSendText method returns NO. If SMS delivery isn’t available, you can notify the user or simply disable the SMS features in your application.
Starting in iOS 5, you can register to be notified of changes to the availability of text message sending by way of the MFMessageComposeViewControllerTextMessageAvailabilityDidChangeNotification notification.
Reasons it might be returning nil:
Device isn't running iOS 4.
Device is an iPod Touch/iPad without iMessage enabled.
No SIM card? (The view now shows in iOS 6; the app is not notified of the message send failure.)
"Device" is actually the simulator. (Perhaps this works in iOS 6 too.)
Similarly, [[MFMailComposeViewController alloc] init] returns nil when no mail accounts are enabled (you can quickly test this by disabling accounts in Settings), but also shows a "No mail accounts configured" alert for you. MFMessageComposeViewController does not do this.

MFMailComposeViewController does not send mail

I am trying to send mail using MFMailComposeViewController. Everything works, except that mails do not get sent, and I always get MFMailComposeResultFailed.
Any pointers? I am NOT using the simulator, and sending mail does work from my device. I do have a connection (testing via Reachability), and [MFMailComposeViewController canSendMail] returns YES.
No compiler warnings in the project, no crashes...
It was a bug in IOS4.
I had both an Exchange mail account and an old, inactive IMAP account on my phone. Apparently, that leads to problems with iOS4. The mails actually were stuck in the outbox. Once I removed the inactive IMAP account, everything worked as expected.
Some readers might be facing this problem:
Make sure you implement the <MFMailComposeViewControllerDelegate> protocol
Here's the code:
// in TestViewController.h
#interface TestViewController : UIViewController<MFMailComposeViewControllerDelegate>
#end
// in TestViewController.m
#interface TestViewController ()
#end
#implementation
- (void) compose {
MFMailComposeViewController *picker = [[MFMailComposeViewController alloc] init];
picker.mailComposeDelegate = self;
[picker setSubject:#"Hello there"];
[picker setToRecipients:#[]];
// Fill out the email body text
NSString *emailBody = #"Hello, sending a message from my app";
[picker setMessageBody:emailBody isHTML:NO];
// use this function. presentModalViewController:... is deprecated
[self presentViewController:picker animated:YES completion:nil];
}
- (void)mailComposeController:(MFMailComposeViewController*)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error
{
[self dismissViewControllerAnimated:YES completion:nil];
}
#end
It's difficult to tell without seeing a code snippet, however you should check the following:
1) you have correctly set the MFMailComposeViewController's delegate and implemented its delegate methods;
2) you have set the mail subject using setSubject:
3) you have set the message body using setMessageBody:isHTML:
and optionally set an attach using addAttachmentData:mimeType:fileName:
4) you have presented to the user your mail compose view controller using something like
[self presentModalViewController:mcvc animated:YES];
Hope this helps.