解决方案是您不要这样做。如果您有一个 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());