首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在捆绑包中使用NSApplication委托

在捆绑包中使用NSApplication委托
EN

Stack Overflow用户
提问于 2016-03-06 22:01:25
回答 3查看 1.1K关注 0票数 2

我正在尝试使用Objective-C为Mac上运行的应用程序创建Unity插件。当我使用URL协议从链接启动我的应用程序时,我需要获得url。我以前没有使用过Objective-C,所以我在尝试让它工作时遇到了麻烦。

我正在使用Unity (download example)提供的一个示例,并将方法更改为获取URL所需的方法,但我的应用程序在_GetUrl方法的nsApplication = [[NSApplication alloc] init];行上崩溃。我不知道我错过了什么/做错了什么。此外,当我想请求url (在第一帧调用)时,_GetUrl是Unity调用的方法,但我担心它可能会在applicationWillFinishLaunching之后调用。那么,我应该在哪里实际设置委托,以便在设置委托之后发生applicationWillFinishLaunching?

我使用一个.h和一个.m脚本,然后编译这个包,并将其作为插件导入到Unity中。这是我的代码:

PluginUrlHandler.h

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

@interface NSApplicationDelegate : NSObject
{
    NSString* urlString;
}

// NSApplication delegate methods
- (void)applicationWillFinishLaunching:(NSNotification *)aNotification;
- (void)handleGetURLEvent:(NSAppleEventDescriptor *)event withReplyEvent:(NSAppleEventDescriptor *)replyEvent;

//Other methods
- (NSString *)getUrl;
@end

PluginUrlHandler.m

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

@implementation NSApplicationDelegate

- (id)init
{
    self = [super init];
    urlString = @"nourl";
    return self;
}

- (void)applicationWillFinishLaunching:(NSNotification *)aNotification
{
    NSAppleEventManager *appleEventManager = [NSAppleEventManager sharedAppleEventManager];
    [appleEventManager setEventHandler:self
                           andSelector:@selector(handleGetURLEvent:withReplyEvent:)
                         forEventClass:kInternetEventClass andEventID:kAEGetURL];

}

- (void)handleGetURLEvent:(NSAppleEventDescriptor *)event withReplyEvent:(NSAppleEventDescriptor *)replyEvent
{
    [event paramDescriptorForKeyword:keyDirectObject] ;

    NSString *urlStr = [[event paramDescriptorForKeyword:keyDirectObject] stringValue];

    urlString = urlStr;
}

- (NSString *)getUrl
{
    return urlString;
}

@end

static NSApplicationDelegate* delegateObject = nil;
static NSApplication* nsApplication = nil;


// Helper method to create C string copy
char* MakeStringCopy (const char* string)
{
    if (string == NULL)
        return NULL;

    char* res = (char*)malloc(strlen(string) + 1);
    strcpy(res, string);
    return res;
}

#if c__plusplus
extern "C" {
#endif

    const char* _GetUrl ()
    {
        if (delegateObject == nil)
        delegateObject = [[NSApplicationDelegate alloc] init];

        if (nsApplication == nil)
            nsApplication = [[NSApplication alloc] init];

        [nsApplication setDelegate:delegateObject];

        return MakeStringCopy([[delegateObject getUrl] UTF8String]);
    }

#if c__plusplus
}
#endif
EN

回答 3

Stack Overflow用户

发布于 2016-03-06 23:32:46

如果您的应用程序崩溃,您需要提供一些信息,例如堆栈跟踪或错误消息,以便我们提供最佳帮助。我假设你收到的错误是这样的:

代码语言:javascript
复制
2016-03-06 10:07:14.388 test[5831:230418] *** Assertion failure in -[NSApplication init], /Library/Caches/com.apple.xbs/Sources/AppKit/AppKit-1404.34/AppKit.subproj/NSApplication.m:1980
2016-03-06 10:07:14.391 test[5831:230418] An uncaught exception was raised
2016-03-06 10:07:14.391 test[5831:230418] Creating more than one Application

您不应该创建自己的NSApplication对象。只需通过引用[NSApplication sharedApplication]来使用系统即可。

不过,一般来说,插件不应该需要NSApplication (或NSApplicationDelegate)。你加载的程序应该已经有一个了,你不想弄乱它。只需创建一个定制的NSObject子类作为AppleEvent处理程序即可。为此,您根本不需要NSApplication (或它的委托)。任何对象都可以是AppleEvent的目标。

在任何情况下,你都不能在插件中使用像applicationDidFinishLaunching:withOptions:这样的东西。太晚了。这个应用程序已经推出很久了。你需要在Unity调用的函数中添加你的AppleEvent处理程序。我不是特别熟悉Unity的插件引擎,所以我不知道是否有一个特殊的"load“函数会被自动调用(我在示例代码中没有看到)。你可能不得不自己给一些东西命名。它必须发生在插件加载之后,但在Get URL Apple事件发生之前(不清楚您希望生成什么)。

只是好奇你到底想干嘛。我从未见过协议处理程序以这种方式使用。

票数 0
EN

Stack Overflow用户

发布于 2016-03-07 02:10:56

创建NSApplication实例看起来非常可疑。通常你不会创建它,因为根据定义它是一个单例。

因此,不是这样:

代码语言:javascript
复制
if (nsApplication == nil)
   nsApplication = [[NSApplication alloc] init];

您应该具有以下内容(获取当前的NSApplication实例):

代码语言:javascript
复制
if (nsApplication == nil)
   nsApplication = [NSApplication sharedApplication];
票数 0
EN

Stack Overflow用户

发布于 2017-05-13 03:57:39

我做了一个关于这方面的教程,参见 Inject code to Mach-O binary

它使用代码注入来设置一个Objective-C类来响应相应的Apple事件。

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

https://stackoverflow.com/questions/35827778

复制
相关文章

相似问题

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