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