How to get OSX app that is currently receiving key events

I am following the cocoa documentation to determine the current main application in OSX - for example an application that receives key events. However, when I execute the following quick API, the API always returns the same value to me - XCode

but it never changes to chrome

or any other application when switching to them. I also tried to execute the compiled program, but instead of showing constantly XCode

, it now shows which terminal application I am running.

What's the correct way to define an application that receives key events from OSX? Is my code broken in this regard?

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

      

+3


source to share


2 answers


You have to do one thing differently, that is, follow the NSWorkSpace notifications that tell you that apps have resigned or become active. This is especially important since you are working in debug mode. In debug mode, Xcode creates the app as a child process. In release mode, it basically does the same thing that invokes the open command in the terminal. In debug mode, if you call this code too early and only once, you won't catch the changes. Remember this dynamically.



+4


source


This thread is a little outdated but was very helpful. I did some research based on the post by Marco and the answer from the uhukaka. Below is the result.

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

      

I am new to both Cocoa and Swift. I don't know if this is effective, but it works for me. I got help from How to create a minimal daemon process in swift 2 command line tool? and Swift 3 NSNotificationCenter Keyboardwillshow / hide among many others.



Swift 4:

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

      

+2


source







All Articles