我正在创建一个简单的 OS X FinderSync为所有文件添加一个菜单项到控制/右键菜单:
[FIFinderSyncController defaultController].directoryURLs = [NSSet setWithObject:[NSURL fileURLWithPath:@"/"]];
它对所有文件都很好(出现菜单项等), /Volumes
中的文件除外 奇怪的是,如果我在 中手动创建一个目录/Volumes
并在那里添加一些文件,右键单击时会出现 FinderSync 的菜单项。但是对于任何已安装卷中的任何文件(即来自已安装的 .dmg),它会失败:没有菜单项出现。
在 directoryURLs
中直接指定一个挂载卷同样失败:
[FIFinderSyncController defaultController].directoryURLs = [NSSet setWithObject:[NSURL fileURLWithPath:@"/Volumes/SomeMountedDMG"]];
好像others有过类似的问题,所以也许这是一个已知的错误/限制?
最佳答案
Finder Sync 扩展监控的文件夹的子文件夹集不跨越文件系统边界。虽然这在 Apple 的文档中没有明确提及,但可以通过经验验证(并且从 macOS 10.13.3 开始仍然如此)。
由于这些扩展的预期用例是监视 Finder 何时显示由同步实用程序(如 Dropbox)维护的特定文件夹,因此 Apple 可能不会将此行为视为限制。然而,许多开发人员将 Finder Sync 扩展实现为一种将任意项目添加到 Finder 中的顶级上下文菜单的方式(不限于出现在服务子菜单中),即使这种用法是 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.
要解决此限制并使扩展的菜单项可用于 Finder 中可见的任何项目,有必要执行以下操作:
- 扫描所有可见的已安装卷,并初始化
FIFinderSyncController
对象的directoryURLs
属性 结果:import FinderSync let finderSync = FIFinderSyncController.default() if let mountedVolumes = FileManager.default.mountedVolumeURLs(includingResourceValuesForKeys: nil, options: .skipHiddenVolumes) { finderSync.directoryURLs = Set<URL>(mountedVolumes) }
- 由于 Finder Sync 扩展是长期存在的进程,请注册
用于安装、卸载和重命名卷的通知,
并相应地更新
directoryURLs
:
(处理卸载和重命名通知留作练习 给读者。)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) } }
关于objective-c - OS X FinderSync 'fails' 用于/卷,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38473610/