繁体   English   中英

使用 Unity3D 在 iPhone 上弹出 SMS ViewController

[英]Making SMS ViewController pop up on iPhone using Unity3D

我无法让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];
        }
    }
}

所以这些:

-(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 “启动”或初始化这个类,我们告诉它这是一个我们需要的对象,把它放在堆上读取 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工作的原因是因为在确保您的delegateObject在内存中之后,您有代码调用UIAlertView 在您的_SMSGO函数中,您没有将对象放入内存中。 所以当你在[delegateObject presentViewController:controller animated:YES];调用delegateObject[delegateObject presentViewController:controller animated:YES]; 它说“哦,我知道delegateObject什么但它等于没有。实际上它没有内存来执行任何事情!” 这就是为什么您可能不会收到任何错误或异常的原因。 代码知道有一个静态对象,但它还没有被设置为任何东西。

解决方案:

首先,void 方法不需要:(id)sender这更像是一个IBAction东西,除非你真的想发送一些东西 - 所以改变-(void)SMS:(id)sender{- (void) SMS { (使用间距也很漂亮。这对眼睛更好)。

其次,将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需要成为一个东西” - 是的。 在名为_init extern "C"部分中创建另一个方法,并在类的AwakeStart函数中从 Unity 运行一次 这将一次性设置您的静态对象,并且再也不会弄乱它。 简单地做到:

void _init() {
    if ( !delegateObject ) {
        delegateObject = [[Delegate alloc] init];
    }
}

!delegateObjectdelegateObject == nil相同,但代码更简洁。 两者都说“我们不知道 dat 是什么” - 好的,现在我们有了我们的delegateObject ,我们可以随意使用delegateObject进行下一次调用。

现在,当您拨打[delegateObject SMS]它会转到- (void) SMS 当您调用self presentViewController它知道 self 指的是iOS Native Object 如果调用presentViewControllerextern "C"它说。“......嗯,嗯,我还没有得到foggiest概念是什么意思” -因为这个原因,我们在您使用一切extern "C"部分的交叉到您的Delegate对象。 这就是extern的全部目的,只是在你的 Obj-C 东西中调用东西。

希望这可以帮助。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM