Xcode 如何检索当前接收关键事件的OSX应用程序

Xcode 如何检索当前接收关键事件的OSX应用程序,xcode,macos,cocoa,swift,Xcode,Macos,Cocoa,Swift,我遵循以下步骤来确定OSX中当前最前端的应用程序-即接收关键事件的应用程序。 但是,当我执行下面的swift时,API总是返回相同的值-XCode,但当我切换到它们时,它不会更改为chrome或任何其他应用程序。我还试图执行编译后的程序,但它不再不断显示XCode,而是显示我正在运行的终端应用程序 确定从OSX接收关键事件的应用程序的正确方法是什么?我在这方面的代码是否被破坏 import Cocoa func getActiveApplication() -> String{

我遵循以下步骤来确定OSX中当前最前端的应用程序-即接收关键事件的应用程序。 但是,当我执行下面的swift时,API总是返回相同的值-
XCode
,但当我切换到它们时,它不会更改为
chrome
或任何其他应用程序。我还试图执行编译后的程序,但它不再不断显示
XCode
,而是显示我正在运行的终端应用程序

确定从OSX接收关键事件的应用程序的正确方法是什么?我在这方面的代码是否被破坏

import Cocoa

func getActiveApplication() -> String{
    // Return the localized name of the currently active application
    let ws = NSWorkspace.sharedWorkspace()
    let frontApp = ws.frontmostApplication
    return frontApp.localizedName
}

var frontMostApp : String
while true {
    frontMostApp = getActiveApplication();
    NSLog("front app: %@", frontMostApp)
    sleep(1);
}

您应该做一件不同的事情,那就是遵循NSWorkSpace通知,通知您应用程序退出活动状态或变为活动状态。 这是关键,尤其是在调试模式下运行时。 在调试模式下,Xcode将作为子进程生成您的应用程序。 在释放模式下,它基本上与在终端中调用open命令相同。
在调试模式下,如果过早调用此代码并且只调用一次,则无法捕获更改。记住它是动态的

此线程有点旧,但非常有用。我根据Marco的帖子和Uchiugaka的回答做了一些研究。结果如下

// swift 3.0
// compile: xcrun -sdk macosx swiftc -framework Cocoa foo.swift -o foo
// run: ./foo

import Cocoa

class MyObserver: NSObject {
    override init() {
        super.init()
        NSWorkspace.shared().notificationCenter.addObserver(self, 
            selector: #selector(printMe(_:)), 
            name: NSNotification.Name.NSWorkspaceDidActivateApplication, 
            object:nil)
    }
    dynamic private func printMe(_ notification: NSNotification) {
        let app = notification.userInfo!["NSWorkspaceApplicationKey"] as! NSRunningApplication
        print(app.localizedName!)
    }
}
let observer = MyObserver()
RunLoop.main.run()
我是可可和斯威夫特的新手。我不知道上述方法是否有效,但它对我有效。我得到了许多人的帮助

Swift 4:

NSWorkspace.shared.notificationCenter.addObserver(self,    // HERE, shared
    selector: #selector(printMe(_:)), 
    name: NSWorkspace.didActivateApplicationNotification,  // HERE
    object:nil)
编辑(Swift 4)

编译器说
printMe
函数必须是
@objc
。(我不知道这是什么意思,但当我在行首预先添加
@objc
时,它起了作用。下面是便于复制粘贴的完整代码

// swift 4.0
// compile: xcrun -sdk macosx swiftc -framework Cocoa foo.swift -o foo
// run: ./foo

import Cocoa

class MyObserver: NSObject {
    override init() {
        super.init()
        NSWorkspace.shared.notificationCenter.addObserver(self, 
            selector: #selector(printMe(_:)), 
            name: NSWorkspace.didActivateApplicationNotification, 
            object:nil)
    }
    @objc dynamic private func printMe(_ notification: NSNotification) {
        let app = notification.userInfo!["NSWorkspaceApplicationKey"] as! NSRunningApplication
        print(app.localizedName!)
    }
}
let observer = MyObserver()
RunLoop.main.run()

“RunLoop.main.run()”有什么作用?如果没有它,应用程序将立即结束。