Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Monitoring app switching on OS X

Tags:

macos

swift

cocoa

I want to know, from within a Swift application, when the user changes from one application to another, just in general.

For example: switching from Google Chrome to a different app like Xcode would trigger this event.

Is there any way to pick up application switching events, like through an event monitor perhaps?

like image 362
Anshul Singh Avatar asked Jul 16 '16 07:07

Anshul Singh


2 Answers

You can add an observer on NSWorkspace.sharedWorkspace().notificationCenter watching for the NSWorkspaceDidActivateApplicationNotification key. You point the selector at one of your methods and grab the information from the userInfo dictionary.

Simple example in AppDelegate:

Swift 2.2

func applicationDidFinishLaunching(notification: NSNotification) {
    NSWorkspace.sharedWorkspace().notificationCenter.addObserver(self,
                                                        selector: #selector(activated),
                                                        name: NSWorkspaceDidActivateApplicationNotification,
                                                        object: nil)
}

func activated(notification: NSNotification) {
    if let info = notification.userInfo,
        app = info[NSWorkspaceApplicationKey],
        name = app.localizedName {
            print(name)
    }
}

Swift 3

func applicationDidFinishLaunching(_ aNotification: Notification) {
    NSWorkspace.shared().notificationCenter.addObserver(self,
                                                        selector: #selector(activated(_:)),
                                                        name: NSNotification.Name.NSWorkspaceDidActivateApplication,
                                                        object: nil)
}

func activated(_ notification: NSNotification) {
    if let info = notification.userInfo,
        let app = info[NSWorkspaceApplicationKey] as? NSRunningApplication,
        let name = app.localizedName 
    {
        print(name)
    }
}
like image 179
Eric Aya Avatar answered Nov 08 '22 15:11

Eric Aya


In Swift 3 you need to use the keyword let for each optional binding. Also, the running application, as extracted from the userInfo dictionary, is of type any, and it needs to be further cast to the NSRunningApplication type.

So the Swift 3 answer given by Eric Aya works but needs small modifications:

func applicationDidFinishLaunching(_ aNotification: Notification) {
    NSWorkspace.shared().notificationCenter.addObserver(self,
                                                        selector: #selector(activated),
                                                        name: NSNotification.Name.NSWorkspaceDidActivateApplication,
                                                        object: nil)
}

func activated(notification: NSNotification) {
    if let info = notification.userInfo,
        let app = info[NSWorkspaceApplicationKey] as? NSRunningApplication,
        let name = app.localizedName {
            print(name)
    }
}

(I would have left this post as comment to the accepted answer, but not enough rep...)

like image 32
tin Avatar answered Nov 08 '22 15:11

tin