MFMessageComposeViewController doesn't do anything in my iPhone 4.x, why? - objective-c

I just upgraded to xcode 4.0.2, my iPhone is 4.3.5 and the MFMessageComposeViewController doesn't do anything. It doesn't say "Can't send an SMS", it doesn't crash or abort, but it doesn't open the dialog to send the message either. It simply does nothing.
-(void)sendSMS:(NSString *)message recipientList:(NSArray *)recipients
{
if ([MFMessageComposeViewController canSendText]) {
MFMessageComposeViewController *controller =
[[[MFMessageComposeViewController alloc] init] autorelease];
if (controller != nil) {
controller.messageComposeDelegate = self;
controller.body = message;
controller.recipients = recipients;
[self presentModalViewController:controller animated:YES];
// [controller release]; // If I really did this it would crash.
}
}
}

OK I finally answered my own question. Now I want no one else to have to go through this.
I was calling this method from just an NSObject. It was a delegate to MFMessageComposeViewControllerDelegate but that made no difference. I had to move this method to my MainViewController, then it worked.

Related

ios: Application tried to present a nil modal view controller on target

I am developing an application,the requirement is to open email composer on a button click of UIAlertView.
message which is in message body of email is copied from UITextView. i am using following code snipt:
-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{
if (buttonIndex == 0)
{
// opening message composer
}
else
{
MFMailComposeViewController *picker = [[MFMailComposeViewController alloc] init];
picker.mailComposeDelegate = self;
[picker setSubject:#"Test mail"];
[picker setMessageBody:messageBody.text isHTML:YES];
[self presentViewController:picker animated:YES completion:NULL];
}
}
// mail compose delegate
- (void)mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error
{
[self dismissViewControllerAnimated:YES completion:NULL];
}
but the issue is that i am getting error saying Application tried to present a nil modal view controller on target. how we can open default mail composer in ios 7?
As per Apple, You should check is MFMailComposeViewController are able to send your mail just before sending
if ([MFMailComposeViewController canSendMail]) {
MFMailComposeViewController *picker = [[MFMailComposeViewController alloc] init];
picker.mailComposeDelegate = self;
[picker setSubject:#"Test mail"];
[picker setMessageBody:messageBody.text isHTML:YES];
[self presentViewController:picker animated:YES completion:NULL];
}
Swift:
if MFMailComposeViewController.canSendMail() else {
// Send mail code
}
Ref : Apple Dev url
Swift 4 version
guard MFMailComposeViewController.canSendMail() else {
print("Mail services are not available")
return
}
sendEmail()
Forgetting Mail account configuration in device settings may also lead to this error. Re check whether a mail account is configured in your device or not.

Cancel button does not dismiss ComposeMail window in iOS simulator

My implementation is pretty simple:
In the .h file, I'm implementing MFMailComposeViewControllerDelegate
And in the .m file, I have the following bit of code:
-(void)MailCurrentViewAsAttachment
{
if ( [MFMailComposeViewController canSendMail] ) {
MFMailComposeViewController * mailComposer = [[MFMailComposeViewController alloc] init];
mailComposer.delegate = self;
[mailComposer addAttachmentData:imageData mimeType:#"image/jpeg" fileName:#"attachment.jpg"];
[self presentViewController:mailComposer animated:YES completion:nil];
}
}
-(void)mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error
{
[self dismissViewControllerAnimated:YES completion:nil];
}
The variable imageData above is of the UIImage type, and I know for sure there's nothing wrong with it: the required image shows up properly in the compose mail window.
However clicking the Cancel button does not dismiss the Compose window. What am I missing?
Note: I'm using iOS 6 with the latest version of xcode, and my app is a Universal app.
You are setting the wrong delegate. You want:
mailComposer.mailComposeDelegate = self;
MFMailComposeViewController extends UINavigationController. So setting delegate is for the UINavigationControllerDelegate.

MPMoviePlayerLoadStateDidChangeNotification works in iOS 5 but not in iOS 6

I want to play a video with an MPMoviePlayerViewController. So in my view controller I register as an observer for MPMoviePlayerLoadStateDidChangeNotification.
I then initialise the MPMoviePlayerViewController:
self.mPlayerVC = [[MPMoviePlayerViewController alloc] initWithContentURL:[NSURL URLWithString:#"<videoURL>"]];
and wait for the notification to arrive. When it does I execute this code:
MPMoviePlayerController* playerController = notification.object;
if ([playerController loadState] & MPMovieLoadStatePlayable) {
if (self.mPlayerVC) {
[self presentMoviePlayerViewControllerAnimated:self.mPlayerVC];
}
}
Anyone an idea why this works for iOS 5 but not for iOS 6? Thanks
There seems to be a bug in iOS 6' MediaPlayer.framework. To get the video to play I call prepareToPlay after initialising the MPMoviePlayerViewController
self.mPlayerVC = [[MPMoviePlayerViewController alloc] initWithContentURL:[NSURL URLWithString:#"<videoURL>"]];
[self.mPlayerVC.moviePlayer prepareToPlay];
Now the notifications come in again but the app crashes when I call [self presentMoviePlayerViewControllerAnimated:self.mPlayerVC]; in the method that is called for the MPMoviePlayerLoadStateDidChangeNotification.
To prevent the crash replace
[self presentMoviePlayerViewControllerAnimated:self.mPlayerVC];
with something like
if ([self respondsToSelector:#selector(presentViewController:animated:completion:)]) {
[self presentViewController:self.mPlayerVC animated:YES completion:nil];
}
else if ([self respondsToSelector:#selector(presentModalViewController:animated:)]) {
[self presentModalViewController:self.mPlayerVC animated:YES];
}

Dismiss mailComposeController

I am trying to dismiss the mail from my app after it's done if user sends or cancels.
But for some reasone this never dismisses. I tried almost everything.
I have also logged this so I will see if it went to dissmiss method. And the problem is there since it never enters the dismiss method.
What am i doing wrong???
- (IBAction)sendmail:(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];
mailComposer.delegate = self;
[mailComposer addAttachmentData:imageData mimeType:#"image/jpeg" fileName:#"attachment.jpg"];
[mailComposer setSubject:#"Hello from My App!"];
NSString *emailBody = #"Sent from My App, Still not in AppStore!";
[mailComposer setMessageBody:emailBody isHTML:YES];
[self presentModalViewController:mailComposer animated:YES];
}
}
-(void)mailComposeController:(MFMailComposeViewController*)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error
{
[self dismissModalViewControllerAnimated:YES];
NSLog (#"mail finished"); // NEVER REACHES THIS POINT.
}
you could replace this line:
[self dismissModalViewControllerAnimated:YES];
with the following line:
[controller dismissModalViewControllerAnimated:YES];
MFMailComposeViewController class inherits from UINavigationController and so its delegate property is 'delegate' for navigation controller 'part' of the class. To handle specific mail composer delegate methods you need to set your object as mailComposeDelegate property:
mailComposer.mailComposeDelegate = self;
SWIFT 5.0:
If you implement the MFMailComposeViewControllerDelegate protocol, you only have to contain the following function in ViewController:
func mailComposeController(_ controller: MFMailComposeViewController, didFinishWith result: MFMailComposeResult, error: Error?)
{
controller.dismiss(animated: true, completion: nil)
}
This function handles everything for you. If the user sends the email the view disappears automatically.
Any further information:
mailComposeController

ShareKit modal view controller won't go away

I'm using ShareKit 0.2.1 on Xcode 4.2 (iOS SDK 5) to share text on Twitter. It shares fine, but the modal view controller wont go away after successfully sharing on after clicking on the cancel button (see below):
And this is my code:
-(IBAction)shareOnTwitter:(id)sender{
// Item to share
NSString *text = #"Go away, modal view controller!";
[SHKTwitter shareText:text];
}
What am I doing wrong?
It is an iOS 5 issue. It's because ShareKit is using a method on UIViewController called parentViewController and according to the Apple docs you can no longer use this in iOS 5. Instead, you must use presentingViewController.
So to fix it in the ShareKit code, go into SHK.m, find the method with signature (void)hideCurrentViewControllerAnimated:(BOOL)animated, and replace it with:
- (void)hideCurrentViewControllerAnimated:(BOOL)animated
{
if (isDismissingView)
return;
if (currentView != nil)
{
// Dismiss the modal view
if ([currentView parentViewController] != nil)
{
self.isDismissingView = YES;
[[currentView parentViewController] dismissModalViewControllerAnimated:animated];
} else if ([currentView presentingViewController] != nil) {
self.isDismissingView = YES;
[[currentView presentingViewController] dismissModalViewControllerAnimated:animated];
} else
self.currentView = nil;
}
}
This works for me on iOS 5.
if (isDismissingView)
return;
if (currentView != nil)
{
// Dismiss the modal view
if ([currentView parentViewController] != nil)
{
self.isDismissingView = YES;
[[currentView parentViewController] dismissModalViewControllerAnimated:animated];
}
else {
//## ADD BELOW ##
self.isDismissingView = YES;
[currentView dismissModalViewControllerAnimated:animated];
self.currentView = nil;
}
}
else {
[[self getTopViewController].navigationController popViewControllerAnimated:YES];
}
This is the code I use in one of my apps.
It dismisses fine.
NSURL *url = [NSURL URLWithString:#"http://itunes.apple.com/us/app/packager/id459511278?l=nl&ls=1&mt=8"];
NSString *twittertext = [[NSString alloc] initWithFormat: #"Tweet Text"];
SHKItem *item = [SHKItem URL:url twittertext];
// Share the item
[SHKTwitter shareItem:item];
[twittertext release];
I have used the following code in my app (ARC disabled)
NSString *text = #"Go away, modal view controller!";
[SHKTwitter shareText:text];
I can confirm it dismisses fine.
You probably changed some code in SHKTwitterForm.m when attempting to make Sharekit ARC compatible. Which resulted in your bug