如何在AppShortcutsProvider中动态添加快捷方式?
动态添加Spotlight快捷入口实现方案

现有静态快捷按钮代码
第一个“新建看板(New Board)”按钮的实现代码如下:
struct MyShortcutsProvider: AppShortcutsProvider { static var appShortcuts: [AppShortcut] { AppShortcut( intent: MyIntent(), phrases: [ «phrase», ], shortTitle: «New Board», systemImageName: «plus» ) } }
问题描述
如何动态添加其他快捷按钮?例如,将用户在应用内创建的文件夹设置为Spotlight搜索快捷入口,实现从Spotlight直接跳转至对应文件夹。
我尝试了如下代码,但未达到预期效果:
struct MyShortcutsProvider: AppShortcutsProvider { static var appShortcuts: [AppShortcut] { return MyShortcutsProvider().createShortcuts() } func createShortcuts() -> [AppShortcut] { var appShortcuts2: [AppShortcut] = [] for item in 0..<3 { appShortcuts2.append( AppShortcut( intent: MyIntent(), phrases: [ "Open \(.applicationName)", ], shortTitle: "\(item)", systemImageName: "circle" ) ) } return appShortcuts2 } }
解决方案
AppShortcutsProvider 定义的是静态系统预置快捷方式,无法动态生成基于用户内容的快捷入口。要实现用户自定义文件夹的Spotlight快捷跳转,需要使用 INVoiceShortcutManager 来创建自定义语音快捷方式,步骤如下:
1. 定义带参数的Intent
首先创建一个支持传入文件夹ID/名称的自定义Intent(比如OpenFolderIntent),在Intent Definition文件中添加参数(如folderIdentifier),用于标识要跳转的文件夹。
2. 创建并添加自定义快捷方式
在用户创建文件夹后,调用以下代码生成对应快捷方式:
import Intents func addFolderShortcut(folderName: String, folderID: String) { // 初始化自定义Intent,设置参数 let intent = OpenFolderIntent() intent.folderIdentifier = folderID intent.suggestedInvocationPhrase = "打开\(folderName)" // 创建快捷方式对象 let shortcut = INShortcut(intent: intent) // 用INVoiceShortcutManager添加快捷方式 INVoiceShortcutManager.shared.addVoiceShortcut(with: shortcut) { voiceShortcut, error in if let error = error { // 处理添加失败的情况 print("添加快捷方式失败: \(error.localizedDescription)") return } // 添加成功 print("快捷方式已添加") } }
3. 处理Intent跳转
在App的入口(如SceneDelegate或App结构体中)处理Intent的激活,实现跳转逻辑:
func handleIntent(intent: INIntent) -> Bool { guard let openFolderIntent = intent as? OpenFolderIntent, let folderID = openFolderIntent.folderIdentifier else { return false } // 根据folderID跳转到对应文件夹页面 navigateToFolder(with: folderID) return true }
4. 更新/删除快捷方式
如果用户修改或删除文件夹,需要同步更新对应的快捷方式:
// 获取所有已添加的快捷方式 INVoiceShortcutManager.shared.getAllVoiceShortcuts { voiceShortcuts, error in guard let voiceShortcuts = voiceShortcuts else { return } for shortcut in voiceShortcuts { if let intent = shortcut.shortcut.intent as? OpenFolderIntent, intent.folderIdentifier == targetFolderID { // 删除快捷方式 INVoiceShortcutManager.shared.deleteVoiceShortcut(with: shortcut.identifier) // 或者更新:先删除再重新添加 break } } }
关键说明
AppShortcutsProvider仅用于定义应用发布时就确定的固定快捷方式,无法动态适配用户生成内容。- 自定义快捷方式会出现在Spotlight搜索中,用户也可以通过Siri触发,同时支持在“设置-Siri与搜索”中管理。
内容的提问来源于stack exchange,提问作者Egor
相关产品推荐
相关产品推荐

