2

I am currently developing a utility program that requires the Finder to be restarted after some changes are made to the user's defaults.

To be on the safe side, I would like to check if the Finder is busy before calling killall Finder (via NSTask). If the Finder is copying files or otherwise busy, I would like to prevent the action and wait a little.

Is there a way to determine if the Finder is busy or if it can safely be killed, in Swift 2.3 on macOS 10.10+ ?

In case this is not possible, is there a safer way for me to refresh (restart) the Finder?

Thanks!

beeb
  • 1,187
  • 11
  • 32
  • Are you sure you want to forcibly kill it, rather than send a quit event followed by an activate one? – dfrib Nov 18 '16 at 14:03
  • I didn't know that was actually possible. Should I use AppleScript for this? Can you post an example as answer? That would help me – beeb Nov 18 '16 at 14:04
  • 1
    See if [this answer](http://stackoverflow.com/a/10226948/4573247) can help you out (obj-C, Cocoa). Alternatively, using AppleScript, see if [this answer](http://stackoverflow.com/a/1462686/4573247) can help you out (obj-C, AppleScript). – dfrib Nov 18 '16 at 14:05

1 Answers1

0

Thanks to @dfri 's comment, I was able to figure out a way (albeit not exactly the one presented in the linked answer) to do this.

Since observing the NSRunningApplication object for the Finder was not possible (the object was deinitialized due to termination before I could remove the observer), I ended up observing NSWorkspaceDidTerminateApplicationNotification from NSWorkspace.sharedWorkspace().notificationCenter

NSWorkspace.sharedWorkspace().notificationCenter.addObserver(self, selector: #selector(MyController.applicationWasTerminated(_:)), name: NSWorkspaceDidTerminateApplicationNotification, object: nil)

I can then remove this observer when my controller is deinitialized, and the selector looks like this :

func applicationWasTerminated(notification: NSNotification?) {
    guard let notif = notification else { return }
    guard let userInfo = notif.userInfo as? [String : AnyObject] else { return }
    guard let identifier = userInfo["NSApplicationBundleIdentifier"] as? String else { return }
    if identifier == "com.apple.finder" {
        NSWorkspace.sharedWorkspace().launchAppWithBundleIdentifier("com.apple.finder", options: NSWorkspaceLaunchOptions.Default, additionalEventParamDescriptor: nil, launchIdentifier: nil)
    }
}
beeb
  • 1,187
  • 11
  • 32