首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用Unity3D实现短信ViewController在iPhone上的弹出

用Unity3D实现短信ViewController在iPhone上的弹出
EN

Stack Overflow用户
提问于 2016-03-16 08:28:03
回答 1查看 169关注 0票数 1

我在让MFMessageComposeUnity3D iOS Plugin一起工作时遇到了问题。

我看到弹出一个带有按钮的警告窗口,但在访问MFMessageComposer时出现错误。似乎无法获得正确弹出窗口的方法。

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

代码语言:javascript
复制
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
#import <MessageUI/MessageUI.h>

@interface Delegate : NSObject <UINavigationControllerDelegate, MFMessageComposeViewControllerDelegate>

@end

和我的iOSBridge.mm文件:

代码语言:javascript
复制
#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];
        }
    }
}
EN

回答 1

Stack Overflow用户

发布于 2016-03-16 13:50:39

因此,这些:

代码语言:javascript
复制
-(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是一个单独的文件。

代码语言:javascript
复制
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上。

代码语言:javascript
复制
        delObj = [[Delegate alloc] init];
    }

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

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

代码语言:javascript
复制
@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.
}

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

现在有了所有这些,你不会调用:

代码语言:javascript
复制
-(void) alertView: (UIAlertView*)alertView clickedButtonAtIndex:(NSInteger)buttonIndex

代码语言:javascript
复制
-(void)SMS:(id)sender{

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

解决方案:

首先,:(id)sender方法不需要IBAction,这更像是一个空方法,除非你真的想发送一些东西--所以把-(void)SMS:(id)sender{改成- (void) SMS { (间隔也很大)。它对眼睛没有好处)。

其次,将SMS中的所有内容都交换为:

代码语言:javascript
复制
- (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对象。然后初始化它。

代码语言:javascript
复制
MFMessageComposeViewController *controller = [[MFMessageComposeViewController alloc] init];

这一行设置了我们刚刚创建的对象的委托 (controller)。但是,为什么能做到这一点呢?因为我们在iOSBridge.h文件中设置了MFMessageComposeViewControllerDelegate。这将告诉您.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中的所有内容都交换为:

代码语言:javascript
复制
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"部分中创建另一个名为_init的方法,并在您的类的AwakeStart函数中从Unity运行此one time。这将设置你的静态对象一次,再也不会弄乱它了。简单地把它做成:

代码语言:javascript
复制
void _init() {
    if ( !delegateObject ) {
        delegateObject = [[Delegate alloc] init];
    }
}

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

现在,当你调用[delegateObject SMS]时,它会转到- (void) SMS。当您调用self presentViewController时,它知道self引用的是iOS本机对象。如果你在extern "C"中调用presentViewController,它会说“……嗯,嗯。我根本不知道这是什么意思”--出于这个原因,我们在你的extern "C"部分使用了everything作为你的Delegate对象的交叉点。这就是extern的全部目的,就是在你的Obj-C东西中调用东西。

希望这能有所帮助。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36024759

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档