是否需要用户界面才能在 Cocoa 中进行全局事件监控?

Posted

技术标签:

【中文标题】是否需要用户界面才能在 Cocoa 中进行全局事件监控?【英文标题】:Is user interface required in order to do global event monitoring in Cocoa? 【发布时间】:2014-02-13 16:07:12 【问题描述】:

我有一个简单的 sn-p(不是 MVC)代码,如下所示

# include <Cocoa/cocoa.h> 

int main(argc, *argv[]) 
    [NSApplication sharedApplication]
    [NSEvent addGlobalMonitorForEventsMatchingMask:NSKeyUpMask handler:^(NSEvent *evt) .... ]
    [NSApp run]

当编译为命令行二进制文件并运行时,全局事件监控工作,在允许程序从系统偏好 -> 隐私和安全之后;然后我将它打包成一个 .app 并运行它,即使在允许应用程序获得隐私和安全性之后,全局监视器也停止工作。

我是 Cocoa 的新手,为了为打包的应用程序实现一个简单的全局监视器,我还需要做什么?

【问题讨论】:

【参考方案1】:

然后我把它打包成一个 .app

您是否将您的 CLI 程序放在一个应用程序包中,或者您是否从一个新的图形 Cocoa 应用程序重新开始?

我建议您使用 Xcode 的项目窗口创建一个新的 GUI 应用程序,然后使用以下 sn-p 作为您的 applicationDidFinishLaunching: implementation:

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification

    Boolean isTrusted = AXIsProcessTrustedWithOptions(CFDictionaryCreate(NULL, (const void*[]) kAXTrustedCheckOptionPrompt , (const void*[]) kCFBooleanTrue , 1, NULL, NULL));
    if(isTrusted)
    
        [NSEvent addGlobalMonitorForEventsMatchingMask:NSKeyUpMask handler:^(NSEvent *evt) NSLog(@"Received NSKeyUp event."); ];
    

这将自动调出“系统偏好设置”窗格,允许用户选择是否应信任您的应用程序。 AXIsProcessTrustedWithOptions 需要 OS X 10.9 (Mavericks)。

更新 在调试全局事件监视器时,“支持辅助设备”存在一些陷阱:

当通过 Xcode“构建并运行”并附带调试器启动应用程序包时,Xcode 还需要在 Privacy pref 窗格中授予 Accessibility 权限 当安装了监视器的 Cocoa 应用程序的窗口位于前台时,全局事件监视器不会接收事件。

【讨论】:

我将 CLI 放入包中。就像说全局监视器在命令行中运行时工作,但在打包并作为普通应用程序运行后不能工作。这两种方法有什么显着不同吗? 您可以在图形 Cocoa 应用程序中安装全局事件监视器而不是嵌入 CLI 程序吗?这可以可靠地工作,并且还可以使以后更容易对应用程序进行沙箱处理。我也更新了我的答案。 我实际上在 xcode 中制作了一个 GUI 应用程序并将我的全局监听器放在 applicationDidFinishLoad:NSNotification 中:直接在 IDE 中运行它并将其归档到应用程序 - 全局监听器以两种方式工作。我知道当托管应用程序位于前面时,全局事件监视器不起作用;根据隐私首选项窗格,我勾选了所有复选框,因此每个应用程序都被授予访问权限。我仍然不明白是什么带来了捆绑和非捆绑应用程序之间的主要区别,以及使用和不使用委托方法之间的区别。

以上是关于是否需要用户界面才能在 Cocoa 中进行全局事件监控?的主要内容,如果未能解决你的问题,请参考以下文章

Cocoa Touch:图形界面构建UIKit

Vant Popover 事件点击两次才能触发

是否可以在 Cocoa 中确定文件是否是从别名打开的?

《从零开始学Swift》学习笔记(Day 68)——Cocoa Touch设计模式及应用之响应者链与触摸事件

《从零开始学Swift》学习笔记(Day 68)——Cocoa Touch设计模式及应用之响应者链与触摸事件

在 CLI Cocoa 应用程序中,如何实现事件循环?