I am following the cocoa documentation to determine the current front most application in OSX - aka the application which receives key events.
However, when I am executing the following swift the API always returns me the same value - XCode
, but it never changes to chrome
or any other application when I switch to them. I also tried to execute the compiled program but instead of constantly showing XCode
it now shows whichever terminal app I am running.
What is the correct way of determining the application that receives the key events from OSX? Is my code in this regard broken?
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);
}
This thread is a bit old but was very helpful. I did some research based on Marco's post and uchuugaka's answer. The following 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 a newbie in both Cocoa and Swift. I don't know if the above is efficient, but it works for me. I got help from How to create a minimal daemon process in a swift 2 command line tool? and Swift 3 NSNotificationCenter Keyboardwillshow/hide among numerous others.
Swift 4:
NSWorkspace.shared.notificationCenter.addObserver(self, // HERE, shared
selector: #selector(printMe(_:)),
name: NSWorkspace.didActivateApplicationNotification, // HERE
object:nil)
Edit (Swift 4)
The compiler says the printMe
function must be @objc
. (I don't know the meaning, but it worked when I prepend @objc
at the beginning of the line. Here is the full code for easy copy-paste.
// 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()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With