【问题标题】:Handling Click Events with NSUserNotification Sent from CLI App使用 CLI 应用程序发送的 NSUserNotification 处理点击事件
【发布时间】:2016-04-16 10:49:59
【问题描述】:

我在 Objective C 中创建了一个 OSX 命令行应用程序,它现在会触发侧边栏通知事件,如下所示:

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]];

我什至使用this technique 让它使用另一个应用程序的图标而不是黑色终端图标。

然而,现在的问题是,当您单击该项目时,它会启动命令行应用程序,而不是我想要的应用程序。如何让点击侧边栏通知启动我单独的 GUI 应用程序?

编辑:也许我需要使用 AppleScript 来告诉我的 CLI 应用程序调用我的 GUI 应用程序并指示它发送通知?这样,事件委托被设置为 GUI 应用程序,而不是 CLI 应用程序。如果是这种情况,我不知道如何启动 AppleScript 并将消息传递给我的 GUI 应用程序,也不知道 GUI 应用程序如何读取该消息。

【问题讨论】:

    标签: objective-c macos cocoa command-line-interface nsusernotification


    【解决方案1】:

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

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

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

    无 GUI 的 Cocoa 应用中介技术

    1。创建一个称为GUI-less Cocoa application 的东西,它将充当您的 CLI 应用程序和 GUI 应用程序之间的中介。如果您创建了 CLI 应用程序,这将消除打开丑陋的终端窗口。步骤:

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

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

    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());
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-06-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-28
      • 1970-01-01
      相关资源
      最近更新 更多