如何在FIFinderSync开发的Finder扩展中正常弹出NSSavePanel?
问题解决方法
核心原因
Finder Sync 扩展运行在独立的扩展进程中,默认没有UI激活上下文,直接调用NSSavePanel的begin方法无法附着到Finder的窗口层级,会被系统拦截导致无法显示。
修复方案
方案1:调整扩展内弹窗逻辑(直接在扩展中实现弹窗)
首先修改你的调用代码,确保运行在主线程且先激活进程上下文,同时改用更稳定的runModal方法触发面板:
@IBAction func sampleAction(_ sender: AnyObject?) { DispatchQueue.main.async { // 先激活扩展进程获取UI焦点 NSApplication.shared.activate(ignoringOtherApps: true) let savePanel = NSSavePanel() savePanel.canCreateDirectories = true savePanel.showsTagField = false savePanel.nameFieldStringValue = "newfile.txt" // 可选配置:默认定位到当前Finder选中的目录 savePanel.directoryURL = FIFinderSyncController.default().selectedItemURLs()?.first // 移除手动设置window level的代码,避免层级冲突 let result = savePanel.runModal() if result == .OK, let targetUrl = savePanel.url { // 执行文件写入逻辑 } } }
同时检查权限配置:
- 确认扩展的Signing & Capabilities下App Sandbox已开启,
User Selected File权限确实为Read/Write - 在扩展的Info.plist中添加
NSAppleEventsUsageDescription权限,描述可填写「需要获取当前Finder选中目录」
方案2:主App联动实现(同类产品通用方案,稳定性更高)
Easy New File等工具均采用该方案,避免扩展进程的UI权限限制:
- 主App配置自定义URL Scheme,比如
newfilecreator:// - 扩展点击菜单后,获取当前选中的目录路径,通过URL Scheme唤起主App并传递目录参数
- 由主App弹出NSSavePanel完成文件创建,主App的沙箱运行环境更稳定,不会出现弹窗被拦截的问题
内容的提问来源于stack exchange,提问作者ssroreo
相关产品推荐
相关产品推荐

