使用Unity3D在iPhone上弹出SMS ViewController

时间:2016-03-16 00:28:03

标签: ios objective-c c unity3d sms

我无法让MFMessageComposeUnity3D iOS Plugin合作。

我有一个警告窗口,弹出按钮,但访问MFMessageComposer时出错。似乎无法正确地弹出窗口。

这是我的iOSBridge.h(链接文件,如果你想):

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

@interface Delegate : NSObject <UINavigationControllerDelegate, MFMessageComposeViewControllerDelegate>

@end

我的iOSBridge.mm文件:

#import "iOSBridge.h"

@implementation Delegate


//Trying to still understand the meaning behind this line.  Why???
-(id)init
{
    return self;
}

//RATE US Button Numbers
//Not entirely sure What I did here but it still bring it up.  This section has nothing to do with SMS
-(void) alertView: (UIAlertView*)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
    //Give back the number of the button

    NSString *inStr = [NSString stringWithFormat:@"%d", (int)buttonIndex];
    const char *cString = [inStr cStringUsingEncoding:NSASCIIStringEncoding];
    UnitySendMessage("Popup", "UserFeedBack", cString);
    NSLog(@"%li", (long)buttonIndex);
} // RATE US button number end

-(void)SMS:(id)sender{

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

    if([MFMessageComposeViewController canSendText]){

        [controller setRecipients:[NSArray arrayWithObjects:nil]];
        [controller setBody:[NSString stringWithFormat:@"Text"]];

        //WHYYY do you not work
        //[self presentViewController:controller animated:YES];

        Delegate *appDelegate = UIApplication.sharedApplication.delegate;
        [appDelegate.window.rootViewController presentViewController:controller animated:YES completion:nil]
    }

}

@end

static Delegate* delegateObject;

extern "C"
{

//A method for unity can run
void _AddNotification(const char* title,
                  const char* body,
                  const char* cancelLabel,
                  const char* firstLabel,
                  const char* secondLabel)

{

//Don't have a full grasp of this delegateObject thing yet.
if(delegateObject ==nil){
    delegateObject = [[Delegate alloc]init];
}

//iOS Alert Pop up view RATE OUR GAME

UIAlertView *alert = [[UIAlertView alloc]
                      initWithTitle: [NSString stringWithUTF8String:title]
                      message:[NSString stringWithUTF8String:body] delegate:delegateObject
                      cancelButtonTitle:[NSString stringWithUTF8String:cancelLabel]
                      otherButtonTitles:[NSString stringWithUTF8String:firstLabel],[NSString stringWithUTF8String:secondLabel], nil];


    [alert show];
} //End of _AddNotification


//SMS Method for Unity to use
void _SMSGO(const char* Mbody){

        MFMessageComposeViewController *controller = [[MFMessageComposeViewController alloc] init];
        if([MFMessageComposeViewController canSendText]){

            NSString *s = [NSString stringWithFormat:@"%s", Mbody];
            controller.body = s;

            //Suppose to Brings up the SMS view not sure why it isnt working or how to make this work
            //If this can work its major progress

            [delegateObject presentViewController:controller animated:YES];
        }
    }
}

1 个答案:

答案 0 :(得分:1)

所以这些:

-(void) alertView: (UIAlertView*)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
    NSString *inStr = [NSString stringWithFormat:@"%d", (int)buttonIndex];
    const char *cString = [inStr cStringUsingEncoding:NSASCIIStringEncoding];
    UnitySendMessage("Popup", "UserFeedBack", cString);
    NSLog(@"%li", (long)buttonIndex);
}

-(void)SMS:(id)sender{

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

    if([MFMessageComposeViewController canSendText]){

        [controller setRecipients:[NSArray arrayWithObjects:nil]];
        [controller setBody:[NSString stringWithFormat:@"Text"]];

        //WHYYY do you not work
        //[self presentViewController:controller animated:YES];

        Delegate *appDelegate = UIApplication.sharedApplication.delegate;
        [appDelegate.window.rootViewController presentViewController:controller animated:YES completion:nil]
    }    
}

实际上,您的网桥根本没有访问代码块。因此,根本不会触及任何内容。

- (id) init是该类的初始值设定项。因此,为了从其他任何内容访问该文件中的任何内容,您必须首先init。想到这一点的更简单方法是:

extern.c是一个单独的文件。

static Delegate *delObj;

extern "C"
{
    void _callMain (const char *hello) {
        /**
         * delObj is a static so it "Will be once it is" so it will be
         * in memory (mallocated) the moment you tell it to be something.
         */
        if (!delObj) {

在这种情况下,我们希望静态对象是Delegate的一个实例(不是一个特别好的名称来设置你的类,它会导致很多混乱)。我们通过调用init“开始”或初始化此类,我们告诉它这是我们需要的对象,将其放在 read this上。

        delObj = [[Delegate alloc] init];
    }

    // Now we can call the function in the next file
    [delObj helloWorld];
}

Delegate.m - 将此视为不同的文件。您可以从extern.c访问此文件,因为(实际上)它只包含在同一个文件中。但这完全是一个单独的实体。您必须从extern.c

访问此“文件
@implementation Delegate

// This is the function we call with [[Delegate alloc] init];
-(id) init {
    // It simply returns itself - saying hey this is the object memory chunk in the heap you want to talk to.
    return self;
}

// This is the function we call with [delObj helloWorld];
- (void) helloWorld {
    NSLog("Hello World"); // This will show up in your console.
}

所以上面的代码有两个函数,一个是“这是你要查找的内存对象” - 一个说“我是一个函数,让我们执行一些东西”。

现在有了所有这些,你没有打电话:

-(void) alertView: (UIAlertView*)alertView clickedButtonAtIndex:(NSInteger)buttonIndex

-(void)SMS:(id)sender{

通过extern "C"_AddNotification之所以有效,是因为您有代码调用UIAlertView AFTER ,确保您的delegateObject在内存中。在_SMSGO函数中,您不会将对象放入内存中。因此,当您在delegateObject中致电[delegateObject presentViewController:controller animated:YES];时,它会说“我知道delegateObject 是什么,但它等于什么。实际上它没有内存来执行什么!”这就是为什么你可能没有得到任何错误或例外。代码知道有一个静态对象,但它还没有被设置为任何东西。

<强> SOLUTION:

首先,void方法不需要:(id)sender更多IBAction的东西,除非你真的想发送一些东西 - 所以将-(void)SMS:(id)sender{更改为- (void) SMS {(使用漂亮的间距。对于眼睛来说,它是 mo'更好

其次,将SMS中的所有内容与:

交换
- (void) SMS {

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

    if([MFMessageComposeViewController canSendText]){

        [controller setRecipients:[NSArray arrayWithObjects:nil]];
        [controller setBody:[NSString stringWithFormat:@"Text"]];

        // We now know why we work!
        [self presentViewController:controller animated:YES];
    }    
}

但等待!并且复制和粘贴。请务必了解您编写的每一行代码。

这一行将一个对象分配到内存中,在本例中为MFMessageComposeViewController对象。然后初始化它。

MFMessageComposeViewController *controller = [[MFMessageComposeViewController alloc] init];

此行设置我们刚刚创建的对象的委托controller)。但 为什么 可以这样做吗?因为我们在MFMessageComposeViewControllerDelegate文件中设置了iOSBridge.h。这会告诉您.mm文件中的所有内容“嘿,如果我们碰巧在某个地方有MFMessage个对象,那么可以访问代理属性。” [controller setMessageComposeDelegate:self];

if ( [MFMessageComposeViewController canSendText] )是人类可读的。

[controller setRecipients:[NSArray arrayWithObjects:nil]];[controller setBody:[NSString stringWithFormat:@"Text"]];

相同

但现在我们需要潜入[self presentViewController:controller animated:YES];

所以在Unity中,他们说“嘿,我们不需要处理所有被调用的本机函数” - 所以他们为你创建了extern能力的访问权限。这允许您从UnityScript方面与Objective-C交谈。 Objective-C只是C的超集,所以这是共同的基础。此处的所有内容都只能调用 Delegate中的函数。这个例子在假extern.c代码块中。唯一要做的就是创建delegateObject并调用函数。现在进行下一步。使用以下内容交换_SMSGO中的所有内容

void _SMSGO (const char *mBody) { // I prefer char *name vs char* name but it doesn't matter

    [delegateObject SMS]; // add mBody as a parameter when you're ready. Handle the stringWithUTF8String on the Objective-C side of things. Yes, this is not the Obj-C side, this is the C side.

}

“但是等等......你只需要delegateObject成为的东西” - 是的。在名为extern "C"的{​​{1}}部分中创建另一种方法,并在班级的_initAwake函数中从Unity运行一次。这将设置您的静态对象一次,再也不会弄乱它。简单地说:

Start

void _init() { if ( !delegateObject ) { delegateObject = [[Delegate alloc] init]; } } !delegateObject相同,但代码更清晰。两者都说“我们不知道什么是数据” - 现在我们已经有了delegateObject == nil,我们可以随意使用delegateObject拨打我们的下一个电话。

现在,当您致电delegateObject时,它会转到[delegateObject SMS]。当你致电- (void) SMS时,它知道自我指的是 iOS原生对象 。如果你在self presentViewController中致电presentViewController,它会说“嗯,嗯。我没有达到最模糊的概念意味着什么” - 因此,我们使用一切extern "C"部分中的strong>作为extern "C"对象的交叉。这就是Delegate事物的全部目的,只是在你的Obj-C中调用东西。

希望这有帮助。