0

I have created an OSX command line application in Objective C and it now fires sidebar notification events like so:

NSUserNotification *n = [[NSUserNotification alloc] init];
n.title = @"My Title";
n.subtitle = @"my subtitle";
n.informativeText = @"some informative text";
[NSUserNotificationCenter.defaultUserNotificationCenter deliverNotification:n];
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];

I even used this technique to make it use another application's icon instead of a black terminal icon.

The trouble now, however, is that when you click the item, it launches the command line application instead of the application that I desire. How can I make the click on the sidebar notification launch my separate GUI application?

EDIT: Perhaps I need to use AppleScript to tell my CLI application to call my GUI application and instruct it to send a notification? That way, the event delegate is set to the GUI application, not the CLI application. If that's the case, I don't know how to make AppleScript launch and pass a message to my GUI application, nor how the GUI application can read that message.

4

1 回答 1

0

解决方案是你不要这样做。如果您有一个 CLI 应用程序需要向用户发布侧边栏通知,并且当用户单击它时,它会打开一个 GUI 配套应用程序,那么有两种方法可以处理这个问题:

• 使您的GUI 应用程序可编写脚本,以便它可以从您的CLI 应用程序接收AppleScript 消息并对其进行操作(如发送侧边栏通知)。这是解释here。这是最优雅的技术。

• 或者,您可以按照以下示例制作一个无 GUI 的 Cocoa 应用程序,充当 CLI 应用程序和 GUI 配套应用程序之间的中介。

GUI-less Cocoa 应用中介技术

1. 创建所谓的无GUI Cocoa 应用程序,它将充当 CLI 应用程序和 GUI 应用程序之间的中介。如果您创建了 CLI 应用程序,这将消除打开丑陋的终端窗口。脚步:

一个。创建一个新的默认 Cocoa 应用程序。

湾。NSMainNibFile从Info.plist 中删除条目。

C。删除 XIB 文件和默认的 AppDelegate 内容(.m、.h)。

d。在 main() 函数的 main.m 中注释掉对 NSApplicationMain 的调用。

e. 将 LSUIElement 键添加到 Info.plist 并将其设置为 YES。

2. 通过将已编译的 GUI 应用程序中的 AppIcon.icns 文件复制到 main.m 文件所在的同一目录中的此无 GUI 应用程序中,为此无 GUI 应用程序设置一个图标。然后,在无 GUI 应用程序的 Info.plist 中,将 CFBundleIconFile 设置为简单的 AppIcon。然后,对您的项目进行清理,以便它使用这个新图标。注意 - XCode 可能会在无法正确显示图标的情况下表现得很奇怪,但是当您在 Finder 中查看它时会很好。

3. 将无 GUI Cocoa 应用程序的 main.m 设置为:

#import <Cocoa/Cocoa.h>

int main(int argc, const char * argv[]) {


    NSString *sTitle = @"";
    NSString *sSubTitle = @"";
    NSString *sText = @"";
    try {
        sTitle = @(argv[1]);
        sSubTitle = @(argv[2]);
        sText = @(argv[3]);
    } catch (...) {
    }

    if ([sTitle isEqualToString:@""]) {
        NSString *script = @"tell app \"";
        // change me to your real GUI application path
        script = [script stringByAppendingString:@"/Applications/Example.app"];
        script = [script stringByAppendingString:@"\" to activate"];
        NSAppleScript *appleScript = [[NSAppleScript alloc] initWithSource:script];
        [appleScript executeAndReturnError:nil];
        exit(0);
    }

    
    NSUserNotification *n = [[NSUserNotification alloc] init];
    n.title = sTitle;
    if (![sSubTitle isEqualToString:@""]) {
        n.subtitle = sSubTitle;
    }
    n.informativeText = sText;
    [NSUserNotificationCenter.defaultUserNotificationCenter deliverNotification:n];
    [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
    return 0;

}

4. 编译此应用程序并将此应用程序文件夹粘贴到您的 /Applications/Example.app/Contents/Resources (当然要更改)文件夹中。

5. 现在您可以使用您的 CLI 应用程序中的以下代码来发送通知,并将使用您的 GUI 应用程序中使用的图标,这非常令人愉快。当用户单击通知时,它将打开您的 GUI 应用程序而不是无 GUI 应用程序。(实际上,当您单击侧边栏通知时,它会打开无 GUI 应用程序,但这不可见。无 GUI 应用程序看到没有参数传递给它,因此它不会显示另一个通知。相反,它知道通过 AppleScript 启动您的 GUI 应用程序。)

#include <string>

std::string sTitle = "Sample Title";
std::string sSubTitle = "sample subtitle";
std::string sText = "some text";
std::string sCmd = "open -a \"";
// change me to the path of your GUI application
sCmd += "/Applications/Example.app";
// change notify.app to the name of your GUI-less application
sCmd += "/Contents/Resources/notify.app";
sCmd += "\" --args ";
sCmd += "\"" + sTitle + "\" ";
sCmd += "\"" + sSubTitle + "\" ";
sCmd += "\"" + sText + "\"";
system(sCmd.c_str());
于 2016-04-16T21:56:57.340 回答