11

I'm creating a simple OS X FinderSync that adds a menu item to the control/right-click menu for all files:

[FIFinderSyncController defaultController].directoryURLs = [NSSet setWithObject:[NSURL fileURLWithPath:@"/"]];

It's working great (the menu item appears, etc.) for all files, except those in /Volumes Oddly, if I manually create a directory in /Volumes and add some files there, the FinderSync's menu item appears when I right-click. However for any files in any mounted Volumes (i.e. from a mounted .dmg), it fails: no menu item appears.

Directly specifying a mounted volume in the directoryURLs similarly fails:

[FIFinderSyncController defaultController].directoryURLs = [NSSet setWithObject:[NSURL fileURLWithPath:@"/Volumes/SomeMountedDMG"]];

It seems others have had similar issues, so maybe this is a known bug/limitation?

pkamb
  • 33,281
  • 23
  • 160
  • 191
patrick
  • 380
  • 2
  • 14
  • 2
    If you've found solution, you can answer your own question. This will help others having same problem. – Tushar Nov 28 '16 at 03:42
  • still no solution....sorry :( Will ping Apple again! – patrick Dec 03 '16 at 06:58
  • Is it only mounted DMGs or is it any read only mounted volume? I just tested a lockable USB drive and the finder options are way different when the USB drive is in locked mode versus unlocked. – CraneStyle Mar 03 '17 at 19:41
  • Having the same issue, did you open a bug with Apple? – StefanS Sep 11 '17 at 07:50

1 Answers1

11

The set of subfolders of a folder monitored by a Finder Sync extension does not cross file system boundaries. Although this is not explicitly mentioned in Apple’s documentation, it can be verified empirically (and is still true as of macOS 10.13.3).

As the intended use case for these extensions is to monitor when the Finder displays specific folders being maintained by synchronization utilities like Dropbox, presumably Apple does not see this behavior as a limitation. However, many developers implement Finder Sync extensions as a way of adding arbitrary items to the top-level contextual menu in the Finder (without being constrained to appear in the Services submenu), even though this usage is explicitly discouraged by Apple:

Make sure the Finder Sync extension point is appropriate for the functionality you plan to provide. The best Finder Sync extensions support apps that sync the contents of a local folder with a remote data source. Finder Sync is not intended as a general tool for modifying the Finder’s user interface.

To work around this limitation and make the extension’s menu item available for any item visible in the Finder, it is necessary to do the following:

  1. Scan for all visible mounted volumes, and initialize the directoryURLs property of the FIFinderSyncController object to the result:
    import FinderSync
    
    let finderSync = FIFinderSyncController.default()
    if let mountedVolumes = FileManager.default.mountedVolumeURLs(includingResourceValuesForKeys: nil,
                                                                  options: .skipHiddenVolumes) {
        finderSync.directoryURLs = Set<URL>(mountedVolumes)
    }
    
  2. Since Finder Sync extensions are long-lived processes, register for notifications of volumes being mounted, unmounted, and renamed, and update directoryURLs accordingly:
    let notificationCenter = NSWorkspace.shared.notificationCenter
    notificationCenter.addObserver(forName: NSWorkspace.didMountNotification, object: nil, queue: .main) {
        (notification) in
        if let volumeURL = notification.userInfo?[NSWorkspace.volumeURLUserInfoKey] as? URL {
            finderSync.directoryURLs.insert(volumeURL)
        }
    }
    
    (Handling unmount and rename notifications are left as an exercise for the reader.)
rsfinn
  • 1,073
  • 14
  • 26