1

I am trying to allow the player to share their score by SMS when the game is over.

I have imported the framework in to my project. Imported in the my viewController.h file.

here is my viewController.h file

#import <UIKit/UIKit.h>
#import <SpriteKit/SpriteKit.h>
#import <MessageUI/MessageUI.h>


@interface myViewController : UIViewController <MFMessageComposeViewControllerDelegate> {
}

@end

I also tried to import into MyScene.h like so:

#import <MessageUI/MessageUI.h>

@interface MyScene : SKScene <MFMessageComposeViewControllerDelegate> {

}

When I want to show the SMS share, I use this code in my MyScene.m file

MFMessageComposeViewController *textComposer = [[MFMessageComposeViewController alloc] init];
[textComposer setMessageComposeDelegate:self];

if ([MFMessageComposeViewController canSendText]) {
    [textComposer setRecipients:[NSArray arrayWithObject:nil]];
    [textComposer setBody:@"Happy Happy Joy Joy!"];
    [self presentViewController:textComposer animated:YES completion:NULL];

} else {
    NSLog(@"Cant send text!");
}

But on this line

[self presentViewController:textComposer animated:YES completion:NULL];

I get an "No visible @interface for 'MyScene' declares the selector 'presentViewController:animated:completion:'" error.

I have tried to search for the last couple hours. Try god knows how many variations and examples from other posts/tutorials(which was good to learn a few things unrelated to this). Nothing seems the work. I starting to run out of hair to pull out. So any help would be great. I am sure for some of you Gurus here this should be a walk in the park. Thanks.

EDIT: I am not using storyboard, or the view controller for buttons/menu/game play etc...hence why I am not able to call the function from within the viewController itself.

EDIT: So I tried what Paulw11 suggested in his link. Now I have the following errors.

in myViewController

    MyScene.MyViewController = self;

I get a "Property 'MyViewController' not found on object of type 'MyScene'" error

also in MyScene.m

- (void)sendToController
{
     NSLog(@"ok");
    // use the already-created spriteViewController
    [_MyViewController sendSMS];
}

[_MyViewController sendSMS]; line I get an "No visible @interface for 'MyViewController' declares the selector 'SendSMS'"

EDIT 2: *EDIT 2:* EDIT 2: *EDIT 2:*

I got it to open up the SMS. Small problem, it does not allow me to dismiss it /cancel.

Here is my sendSMS code:

 -(void) sendSMS {

MFMessageComposeViewController *textComposer = [[MFMessageComposeViewController alloc] init];
[textComposer setMessageComposeDelegate:self];

if ([MFMessageComposeViewController canSendText]) {
    [textComposer setRecipients:[NSArray arrayWithObject:@" "]];

    NSString *body = [NSString stringWithFormat:@"Happy Day!: %i.   ", _score];
    [textComposer setBody:body];

    UIViewController *vc = self.view.window.rootViewController;
    [vc presentViewController: textComposer animated: YES completion:nil];

} else {
    NSLog(@"Cant send text!");
}
}

Here is my dismiss code:

-(void)messageComposeViewController:(MFMessageComposeViewController *)controller   didFinishWithResult:(MessageComposeResult)result {

    UIViewController *vc = self.view.window.rootViewController;
    [vc dismissViewControllerAnimated:YES completion:NULL];

}

EDIT 3

The following code gives me the NSLog at the correct times, but does not dismiss the window.

- (void)messageComposeViewController:(MFMessageComposeViewController *)controller
             didFinishWithResult:(MessageComposeResult)result
{
    UIViewController *vc = self.view.window.rootViewController;

// Notifies users about errors associated with the interface
switch (result)
{
    case MessageComposeResultCancelled:
       NSLog(@"Result: SMS sending canceled");
        break;
    case MessageComposeResultSent:
        NSLog(@"Result: SMS sent");
        break;
    case MessageComposeResultFailed:
        NSLog(@"Result: SMS sending failed");
        break;
    default:
        NSLog(@"Result: SMS not sent");
        break;
}

[vc dismissViewControllerAnimated:YES completion:NULL];
}
CodeSmile
  • 64,284
  • 20
  • 132
  • 217
the_pantless_coder
  • 2,297
  • 1
  • 17
  • 30
  • possible duplicate of [How do I present a UIViewController from SKScene?](http://stackoverflow.com/questions/19438719/how-do-i-present-a-uiviewcontroller-from-skscene) – Paulw11 Mar 23 '14 at 00:22
  • The problem is that you are invoking `presentViewController` on an `SKScene`, not on a `UIViewController`. You must have a root view controller in your App. You need to get a reference to that and use that to present the textComposer controller. – Paulw11 Mar 23 '14 at 00:23
  • @Paulw11 Thanks for the link, I tried, what was suggested. But no luck. How would I reference my view controller from my SKScene? – the_pantless_coder Mar 23 '14 at 00:36
  • Is your self.view.window.rootViewController in your SKScene non-nil ? What about your appDelegate.window.rootViewController ? – Paulw11 Mar 23 '14 at 00:53
  • @Paulw11 please see my edit in my question. – the_pantless_coder Mar 23 '14 at 01:17
  • You need to declare MyViewController as a property of your MyScene class. In MyScene.h add @property (retain,monatomic) myViewController *MyViewController; Also make sure that you have imported myViewController.h into your myscenecontroller.m – Paulw11 Mar 23 '14 at 02:41

1 Answers1

2

If you refer to the MFMessageComposeViewController Class Reference you will see that you need to present it modally using presentModalViewController:animated:. You are also responsible for dismissing it via your delegate object once you are done.

I suggest you have a look at the Message Composer sample code for an example of using the MFMessageComposeViewController class.

UPDATE

You can just dismiss the view controller that was passed to your delegate method -

- (void)messageComposeViewController:(MFMessageComposeViewController *)controller
         didFinishWithResult:(MessageComposeResult)result
{

// Notifies users about errors associated with the interface
switch (result)
{
    case MessageComposeResultCancelled:
       NSLog(@"Result: SMS sending canceled");
    break;
    case MessageComposeResultSent:
        NSLog(@"Result: SMS sent");
    break;
    case MessageComposeResultFailed:
        NSLog(@"Result: SMS sending failed");
    break;
    default:
        NSLog(@"Result: SMS not sent");
    break;
}

[controller dismissViewControllerAnimated:YES completion:NULL];
}
Paulw11
  • 108,386
  • 14
  • 159
  • 186