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