Question

I have an OS X application that needs to respond to a volume being mounted or unmounted.

I've already solved this problem by retrieving the list of volumes periodically and checking for changes, but I'd like to know if there is a better way.

Was it helpful?

Solution

Register to the notification center you get from [[NSWorkspace sharedWorkspace] notificationCenter] and then process the notifications you are interested in. These are the volume related ones: NSWorkspaceDidRenameVolumeNotification, NSWorkspaceDidMountNotification, NSWorkspaceWillUnmountNotification and NSWorkspaceDidUnmountNotification.

OTHER TIPS

The NSWorkspace approach is exactly the kind of thing I was looking for. A few lines of code later, I have a much better solution than using a timer.

-(void) monitorVolumes
{
    [[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:self selector: @selector(volumesChanged:) name:NSWorkspaceDidMountNotification object: nil];
    [[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:self selector: @selector(volumesChanged:) name:NSWorkspaceDidUnmountNotification object:nil];
}

-(void) volumesChanged: (NSNotification*) notification
{
    NSLog(@"dostuff");
}

Swift 4 version:

Declare NSWorkspace in applicationDidFinishLaunching and add observers for mount and unmount events.

let workspace = NSWorkspace.shared

workspace.notificationCenter.addObserver(self, selector: #selector(didMount(_:)), name: NSWorkspace.didMountNotification, object: nil)
workspace.notificationCenter.addObserver(self, selector: #selector(didUnMount(_:)), name: NSWorkspace.didUnmountNotification, object: nil)

Capture mount and unmount events in:

@objc func didMount(_ notification: NSNotification)  {
    if let devicePath = notification.userInfo!["NSDevicePath"] as? String {
        print(devicePath)
    }
}
@objc func didUnMount(_ notification: NSNotification)  {
    if let devicePath = notification.userInfo!["NSDevicePath"] as? String {
        print(devicePath)
    }
}

It will print device path e.g /Volumes/EOS_DIGITAL Here are the constants you can read from userInfo.

NSDevicePath, 
NSWorkspaceVolumeLocalizedNameKey
NSWorkspaceVolumeURLKey

Do you know SCEvents? It allows you to be notified when the contents of an observed folder change (/Volumes). This way you don't have to use a timer to periodically check the contents.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top