macOS 中如何让 NSSharingServicePicker 显示“编辑扩展…”?
结论
优先使用 NSSharingServicePicker 展示系统共享界面。公开 API 中没有用于强制显示“Edit Extensions…”的文档化开关。Safari、备忘录和自己的应用表现不同,也不足以说明该入口需要 private API。
直接展示系统 picker 时,界面由系统管理;自行构建 NSMenu 时,需要自行提供希望保留的管理入口。当前问题没有给出 macOS 版本、展示代码和 delegate 实现,因此还不能确定入口缺失的具体原因。
为什么共享服务列表不等于完整共享界面
Apple 文档说明,NSSharingServicePicker 在 macOS 12 及更早版本中显示菜单,在 macOS 13 及以后显示包含预览和共享服务的 popover。不同系统版本的入口位置和界面形式不能直接等同。NSSharingServicePicker 文档
“Edit Extensions…”用于管理共享扩展,Mail、AirDrop 等服务则用于执行共享操作。从共享服务数组重建菜单时,不能假定它也会带上系统的管理入口。
NSSharingServicePickerDelegate 的 sharingServicePicker(_:sharingServicesForItems:proposedSharingServices:) 可以增加、删除和重排共享服务,但该方法返回的是 [NSSharingService],没有提供控制“Edit Extensions…”的参数。delegate 方法文档
先用最小代码确认系统 picker 的表现
暂时移除自定义 delegate 和自建菜单逻辑,在同一台 Mac、同一用户账户下直接展示 picker:
import AppKit
@MainActor
final class ViewController: NSViewController {
private var sharingPicker: NSSharingServicePicker?
@IBAction func share(_ sender: NSButton) {
let picker = NSSharingServicePicker(
items: [URL(string: "https://example.com")!]
)
sharingPicker = picker
picker.show(
relativeTo: sender.bounds,
of: sender,
preferredEdge: .minY
)
}
}
示例假设按钮已连接到 share(_:),用于排除应用自身的菜单拼装和服务筛选逻辑。它不保证某个 macOS 版本一定会在指定位置显示特定文字的入口。
按以下顺序比较:
- 记录 macOS 版本、实际传入的
items类型,以及完整共享界面的截图。 - 检查最小示例中是否有管理扩展的入口,包括 popover 底部等位置。
- 如果最小示例正常,逐步恢复 delegate、工具栏封装和菜单定制,定位差异。
- 如果最小示例也缺失该入口,保留复现工程,通过 Feedback Assistant 报告系统行为。
共享内容类型会影响可用服务,但不能据此断言它一定决定管理入口是否显示。Apple 的设置说明提到,扩展即使已经启用,也可能因为不支持当前共享内容而不出现在共享菜单中。共享扩展设置说明
在自己的菜单中接入系统共享入口
如果应用需要在普通菜单中提供共享操作,可以考虑 standardShareMenuItem。Apple 将它定义为用于展示指定内容的 picker 的菜单项:standardShareMenuItem 文档
let picker = NSSharingServicePicker(items: items)
sharingPicker = picker
menu.addItem(picker.standardShareMenuItem)
这里假设 items、menu 和保存 picker 的属性已经存在,且目标 SDK、部署版本支持该属性。它是进入系统 picker 的标准菜单项,不能当作可任意编辑的系统共享服务子菜单,也不能据此保证所有系统版本都会展示相同的管理入口。
如果还需要其他应用操作,可以将自己的 NSMenuItem 放在这个标准入口旁边。若要向 picker 内加入自定义共享服务,可以使用前述 delegate 方法添加 NSSharingService。
何时需要手动提供管理入口
如果整个共享菜单由应用自行构建,且产品需要提供管理扩展的功能,可以增加“管理共享扩展…”菜单项。一个保守的兜底方案是通过 NSWorkspace 打开系统设置,并提示用户进入共享扩展设置。NSWorkspace 提供公开的应用查找和启动接口。应用查找接口、应用启动接口
在 Apple 当前设置指南描述的界面中,共享扩展位于“系统设置 → 通用 → 登录项与扩展”的扩展区域。不同 macOS 版本的设置布局可能不同,应按实际支持的版本提供指引。不要将其与文件共享、屏幕共享所在的“共享”设置混淆。共享扩展设置说明
如果希望直接跳转到某个设置子页面,需要单独确认所用定位方式在目标系统上的支持情况,不能把未文档化的 URL 参数当作稳定 API。
是否应该使用 private API
目前没有依据证明这个问题必须通过 private API 解决,也没有足够信息识别所谓内部显示条件。公开文档没有承诺“Edit Extensions…”在所有展示场景中都会出现,也没有给出完整的出现条件。
实现时应先保留系统 picker,通过最小示例确认差异;自行构建菜单时,再提供独立的管理入口。不要依赖内部视图层级、私有 selector,或通过标题查找并修改系统控件来强行补齐界面。
备注:内容仅供参考。
