关于 axiom-app-shortcuts-ref
面向 Apple 平台开发者的 App Shortcuts 框架参考技能,涵盖快捷指令配置、Siri 与 Spotlight 发现及调试。重点区分 App Intents 与预配置快捷指令,并提供参数化短语等实现指导。
主要功能
- 01配置 AppShortcutsProvider
- 02设计 Siri 与 Spotlight 短语
- 03创建参数化快捷指令
- 04使用 SiriTipView 推广快捷指令
- 05动态更新快捷指令参数
- 06排查快捷指令发现问题
适用场景
- 01为应用核心操作添加快捷指令
- 02让 Siri 和 Spotlight 触发应用操作
- 03减少 Siri 执行时的参数追问
- 04排查快捷指令未显示的问题
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ charleswiltgen/ axiom --skill axiom-app-shortcuts-ref安装后在 Claude Code 中输入/axiom-app-shortcuts-ref确认已加载。
详细介绍
App 快捷指令参考
概览
全面介绍 App Shortcuts 框架,帮助你让 App 操作立即出现在 Siri、Spotlight、操作按钮、控制中心及其他系统体验中。App Shortcuts 是预先配置好的 App Intents,App 安装后即可使用,无需用户进行任何设置。
关键区别 App Intents 是操作;App Shortcuts 则是预先配置好的“入口”,可让这些操作立即在整个系统中被发现。
何时使用此技能
在以下情况下使用此技能:
- 为你的 App 实现 AppShortcutsProvider
- 添加用于通过 Siri 调用的建议短语
- 配置 Spotlight 即时可用性
- 创建带参数的快捷指令(跳过 Siri 澄清步骤)
- 使用 NegativeAppShortcutPhrase 防止误触发(iOS 17+)
- 使用 SiriTipView 推广快捷指令
- 使用 updateAppShortcutParameters() 动态更新快捷指令
- 调试快捷指令未显示在“快捷指令”App 或 Spotlight 中的问题
- 在 App Intents 和 App Shortcuts 之间进行选择
请勿将此技能用于:
- 一般的 App Intents 实现(使用 app-intents-ref)
- Core Spotlight 索引(使用 core-spotlight-ref)
- 整体可发现性策略(使用 app-discoverability)
相关技能
- app-intents-ref — 完整的 App Intents 实现参考
- app-discoverability — 提升 App 可发现性的策略指南
- core-spotlight-ref — Core Spotlight 和 NSUserActivity 集成
App Shortcuts 与 App Intents
| 方面 | App Intent | App Shortcut |
|---|---|---|
| 发现方式 | 必须在“快捷指令”App 中找到 | 安装后立即可用 |
| 配置方式 | 用户在“快捷指令”中配置 | 由开发者预先配置 |
| Siri 激活 | 需要设置自定义短语 | 使用提供的短语即可立即运行 |
| Spotlight | 需要 donation 或 IndexedEntity | 自动显示 |
| 操作按钮 | 无法直接访问 | 可立即分配 |
| 设置时间 | 每位用户需几分钟 | 无需设置 |
何时使用 App Shortcuts 每个 App 都应为核心功能提供 App Shortcuts。它们无需用户付出任何努力,就能大幅提升可发现性。
核心概念
AppShortcutsProvider 协议
必须遵循 你的 App 必须恰好有一个类型遵循 AppShortcutsProvider。
struct MyAppShortcuts: AppShortcutsProvider {
// Required: Define your shortcuts
@AppShortcutsBuilder
static var appShortcuts: [AppShortcut] { get }
// Optional: Branding color
static var shortcutTileColor: ShortcutTileColor { get }
// Optional: Dynamic updates
static func updateAppShortcutParameters()
// Optional: Negative phrases (iOS 17+)
static var negativePhrases: [NegativeAppShortcutPhrase] { get }
}
平台支持 iOS 16+、iPadOS 16+、macOS 13+、tvOS 16+、watchOS 9+
AppShortcut 结构
将一个 AppIntent 与语音短语及元数据关联起来。
AppShortcut(
intent: StartMeditationIntent(),
phrases: [
"Start meditation in \(.applicationName)",
"Begin mindfulness with \(.applicationName)"
],
shortTitle: "Meditate",
systemImageName: "figure.mind.and.body"
)
组成部分:
intent— 要执行的 App Intentphrases— 用于 Siri/Spotlight 的语音/输入短语shortTitle— “快捷指令”App 磁贴的短标签systemImageName— 用于视觉呈现的 SF Symbol
AppShortcutPhrase(建议短语)
字符串插值 短语使用 \(.applicationName) 动态包含你的 App 名称。
phrases: [
"Start meditation in \(.applicationName)",
"Meditate with \(.applicationName)"
]
用户在 Siri/Spotlight 中看到:
- “在 Calm 中开始冥想”
- “使用 Calm 冥想”
为何重要 系统会使用这些确切短语,通过 Siri 触发你的意图,并在 Spotlight 中显示建议。
@AppShortcutsBuilder
用于定义快捷指令数组的结果构建器。
@AppShortcutsBuilder
static var appShortcuts: [AppShortcut] {
AppShortcut(intent: OrderIntent(), /* ... */)
AppShortcut(intent: ReorderIntent(), /* ... */)
if UserDefaults.standard.bool(forKey: "premiumUser") {
AppShortcut(intent: CustomizeIntent(), /* ... */)
}
}
结果构建器功能:
- 条件快捷指令(if/else)
- 循环生成快捷指令(for-in)
- 内联数组构造
短语模板模式
基本短语(无参数)
AppShortcut(
intent: StartWorkoutIntent(),
phrases: [
"Start workout in \(.applicationName)",
"Begin exercise with \(.applicationName)",
"Work out in \(.applicationName)"
],
shortTitle: "Start Workout",
systemImageName: "figure.run"
)
优势:
- 简单易发现
- 适用于所有用户
- 不存在参数歧义
适用情况 意图没有必需参数,或参数具有默认值。
参数化短语(跳过澄清)
预先配置带有特定参数值的意图,以跳过 Siri 的澄清步骤。
// Intent with parameters
struct StartMeditationIntent: AppIntent {
static var title: LocalizedStringResource = "Start Meditation"
@Parameter(title: "Type")
var meditationType: MeditationType?
@Parameter(title: "Duration")
var duration: Int?
}
// Shortcuts with different parameter combinations
@AppShortcutsBuilder
static var appShortcuts: [AppShortcut] {
// Generic version (will ask for parameters)
AppShortcut(
intent: StartMeditationIntent(),
phrases: ["Start meditation in \(.applicationName)"],
shortTitle: "Meditate",
systemImageName: "figure.mind.and.body"
)
// Specific versions (skip parameter step)
AppShortcut(
intent: StartMeditationIntent(
meditationType: .mindfulness,
duration: 10
),
phrases: [
"Start quick mindfulness in \(.applicationName)",
"10 minute mindfulness in \(.applicationName)"
],
shortTitle: "Quick Mindfulness",
systemImageName: "brain.head.profile"
)
AppShortcut(
intent: StartMeditationIntent(
meditationType: .sleep,
duration: 20
),
phrases: [
"Start sleep meditation in \(.applicationName)"
],
shortTitle: "Sleep Meditation",
systemImageName: "moon.stars.fill"
)
}
优点:
- 一句话即可完成(无需后续提问)
- 为常见使用场景带来更好的用户体验
- Spotlight 会显示具体的快捷指令
**权衡:**快捷指令越多,Shortcuts 应用中的界面就越杂乱。在常见场景(3-5 个快捷指令)和灵活性(带参数的通用快捷指令)之间取得平衡。
NegativeAppShortcutPhrase(iOS 17+)
训练系统不要因某些短语而调用你的应用。
struct MeditationAppShortcuts: AppShortcutsProvider {
@AppShortcutsBuilder
static var appShortcuts: [AppShortcut] {
AppShortcut(
intent: StartMeditationIntent(),
phrases: ["Start meditation in \(.applicationName)"],
shortTitle: "Meditate",
systemImageName: "figure.mind.and.body"
)
}
// Prevent false positives
static var negativePhrases: [NegativeAppShortcutPhrase] {
NegativeAppShortcutPhrases {
"Stop meditation"
"Cancel meditation"
"End session"
}
}
}
适用场景:
- 听起来与你的快捷指令相似、但意思相反的短语
- 用户可能会说、但不应触发你的应用的常见短语
- 多个应用具有相似功能时用于消歧
**平台:**iOS 17.0+、iPadOS 17.0+、macOS 14.0+、tvOS 17.0+、watchOS 10.0+
发现界面组件
SiriTipView — 在应用内推广快捷指令
在应用界面中直接显示快捷指令的语音短语。
import AppIntents
import SwiftUI
struct OrderConfirmationView: View {
@State private var showSiriTip = true
var body: some View {
VStack {
Text("Order confirmed!")
// Show Siri tip after successful order
SiriTipView(intent: ReorderIntent(), isVisible: $showSiriTip)
.siriTipViewStyle(.dark)
}
}
}
要求:
- 必须在 AppShortcut 中使用该意图(否则会显示空视图)
- isVisible 绑定控制显示状态
样式:
.automatic— 根据环境自动调整.light— 浅色背景.dark— 深色背景
**最佳实践:**在用户完成操作后显示,提示他们下次可以用更简单的方式完成操作。
ShortcutsLink — 链接到 Shortcuts 应用
打开 Shortcuts 应用中你的应用页面,其中列出了所有可用的快捷指令。
import AppIntents
import SwiftUI
struct SettingsView: View {
var body: some View {
List {
Section("Siri & Shortcuts") {
ShortcutsLink()
// Displays "Shortcuts" with standard link styling
}
}
}
}
适用场景:
- 设置屏幕
- 帮助/支持部分
- 引导流程
**优点:**用户轻点一次即可查看应用中的所有快捷指令,并看到建议的短语。
ShortcutTileColor — 品牌塑造
为 Shortcuts 应用中的快捷指令设置颜色。
struct CoffeeAppShortcuts: AppShortcutsProvider {
static var shortcutTileColor: ShortcutTileColor = .tangerine
@AppShortcutsBuilder
static var appShortcuts: [AppShortcut] {
// ...
}
}
可用颜色:
| 颜色 | 使用场景 |
|---|---|
.blue | 默认、专业 |
.tangerine | 活力、食品/饮料 |
.purple | 创意、冥想 |
.teal | 健康、养生 |
.red | 紧急、重要 |
.pink | 生活方式、社交 |
.navy | 商务、金融 |
.yellow | 效率、笔记 |
.lime | 健身、户外 |
完整列表:.blue、.grape、.grayBlue、.grayBrown、.grayGreen、.lightBlue、.lime、.navy、.orange、.pink、.purple、.red、.tangerine、.teal、.yellow
**选择颜色:**选择与应用图标或品牌形象相符的颜色。
动态更新
updateAppShortcutParameters()
在参数选项发生变化时调用,以刷新已存储的快捷指令。
struct MeditationAppShortcuts: AppShortcutsProvider {
@AppShortcutsBuilder
static var appShortcuts: [AppShortcut] {
// Shortcuts can reference dynamic data
for session in MeditationData.favoriteSessions {
AppShortcut(
intent: StartSessionIntent(session: session),
phrases: ["Start \(session.name) in \(.applicationName)"],
shortTitle: session.name,
systemImageName: session.iconName
)
}
}
static func updateAppShortcutParameters() {
// Called automatically when needed
// Override only if you need custom behavior
}
}
// In your app, when data changes
extension MeditationData {
func markAsFavorite(_ session: Session) {
favoriteSessions.append(session)
// Update App Shortcuts to reflect new data
MeditationAppShortcuts.updateAppShortcutParameters()
}
}
调用时机:
- 用户添加/移除收藏项
- 可用选项发生变化
- 应用数据结构更新
**自动调用:**系统会定期调用此方法,但当你确认数据已更改时,也可以强制更新。
完整实现示例
步骤 1:定义 App Intents
import AppIntents
struct OrderCoffeeIntent: AppIntent {
static var title: LocalizedStringResource = "Order Coffee"
static var description = IntentDescription("Orders coffee for pickup")
@Parameter(title: "Coffee Type")
var coffeeType: CoffeeType
@Parameter(title: "Size")
var size: CoffeeSize
@Parameter(title: "Customizations")
var customizations: String?
static var parameterSummary: some ParameterSummary {
Summary("Order \(\.$size) \(\.$coffeeType)") {
\.$customizations
}
}
func perform() async throws -> some IntentResult {
let order = try await CoffeeService.shared.order(
type: coffeeType,
size: size,
customizations: customizations
)
return .result(
value: order,
dialog: "Your \(size) \(coffeeType) is ordered for pickup"
)
}
}
struct ReorderLastIntent: AppIntent {
static var title: LocalizedStringResource = "Reorder Last Coffee"
static var description = IntentDescription("Reorders your most recent coffee")
static var openAppWhenRun: Bool = false
func perform() async throws -> some IntentResult {
guard let lastOrder = try await CoffeeService.shared.lastOrder() else {
throw CoffeeError.noRecentOrders
}
try await CoffeeService.shared.reorder(lastOrder)
return .result(
dialog: "Reordering your \(lastOrder.coffeeName)"
)
}
}
enum CoffeeType: String, AppEnum {
case latte, cappuccino, americano, espresso
static var typeDisplayRepresentation: TypeDisplayRepresentation = "Coffee"
static var caseDisplayRepresentations: [CoffeeType: DisplayRepresentation] = [
.latte: "Latte",
.cappuccino: "Cappuccino",
.americano: "Americano",
.espresso: "Espresso"
]
}
enum CoffeeSize: String, AppEnum {
case small, medium, large
static var typeDisplayRepresentation: TypeDisplayRepresentation = "Size"
static var caseDisplayRepresentations: [CoffeeSize: DisplayRepresentation] = [
.small: "Small",
.medium: "Medium",
.large: "Large"
]
}
步骤 2:创建 AppShortcutsProvider
import AppIntents
struct CoffeeAppShortcuts: AppShortcutsProvider {
@AppShortcutsBuilder
static var appShortcuts: [AppShortcut] {
// Generic order (will ask for parameters)
AppShortcut(
intent: OrderCoffeeIntent(),
phrases: [
"Order coffee in \(.applicationName)",
"Get coffee from \(.applicationName)"
],
shortTitle: "Order",
systemImageName: "cup.and.saucer.fill"
)
// Common specific orders (skip parameter step)
AppShortcut(
intent: OrderCoffeeIntent(
coffeeType: .latte,
size: .medium
),
phrases: [
"Order my usual from \(.applicationName)",
"Get my regular coffee from \(.applicationName)"
],
shortTitle: "Usual Order",
systemImageName: "star.fill"
)
// Reorder last
AppShortcut(
intent: ReorderLastIntent(),
phrases: [
"Reorder coffee from \(.applicationName)",
"Order again from \(.applicationName)"
],
shortTitle: "Reorder",
systemImageName: "arrow.clockwise"
)
}
// Branding
static var shortcutTileColor: ShortcutTileColor = .tangerine
// Prevent false positives (iOS 17+)
static var negativePhrases: [NegativeAppShortcutPhrase] {
NegativeAppShortcutPhrases {
"Cancel coffee order"
"Stop coffee"
}
}
}
步骤 3:在界面中推广
import SwiftUI
import AppIntents
struct OrderConfirmationView: View {
@State private var showReorderTip = true
var body: some View {
VStack(spacing: 20) {
Image(systemName: "checkmark.circle.fill")
.font(.system(size: 60))
.foregroundColor(.green)
Text("Order Placed!")
.font(.title)
Text("Your coffee will be ready in 10 minutes")
.foregroundColor(.secondary)
// Promote reorder shortcut
if showReorderTip {
SiriTipView(intent: ReorderLastIntent(), isVisible: $showReorderTip)
.siriTipViewStyle(.dark)
.padding(.top)
}
// Link to see all shortcuts
Section {
ShortcutsLink()
} header: {
Text("See all available shortcuts")
.font(.caption)
}
}
.padding()
}
}
App Shortcuts 的显示位置
实现后,你的 App Shortcuts 可在以下位置使用:
| 位置 | 用户体验 |
|---|---|
| Siri | 使用提供的短语进行语音激活 |
| Spotlight | 搜索操作或短语 → 立即执行 |
| Shortcuts 应用 | 预先填充的快捷指令,无需配置 |
| Action Button(iPhone 15 Pro) | 可分配给硬件按钮 |
| Apple Watch Ultra | 分配给 Action Button |
| Control Center | 将快捷指令添加为控制项 |
| 锁屏小组件 | 无需解锁即可执行快捷操作 |
| Apple Pencil Pro | 分配挤压手势 |
| 专注模式过滤条件 | 根据上下文进行过滤 |
**立即可用:**应用安装后,所有位置都会立即生效。无需用户进行设置。
测试与调试
验证快捷指令是否显示在“快捷指令”App 中
- 在设备上构建并运行你的 App
- 打开“快捷指令”App
- 点击“+”以创建新快捷指令
- 搜索你的 App 名称
- 验证快捷指令是否显示,并确认标题和图标正确
如果快捷指令没有显示:
- 确保 AppShortcutsProvider 位于主 App 目标中
- 检查 AppIntents 的
isDiscoverable是否为 true(默认值) - 重新构建并重新安装 App
- 检查控制台中是否有 AppShortcuts 错误
测试 Siri 调用
- 呼叫 Siri
- 说出一条建议短语
- 验证 Siri 是否执行了该意图
示例:
- 你:“在 CoffeeApp 订一杯咖啡”
- Siri:“要什么尺寸和类型?”
- 你:“中杯拿铁”
- Siri:“已为你订好一杯中杯拿铁,供你自取”
如果 Siri 无法识别短语:
- 检查短语是否包含
\(.applicationName) - 确认短语位于 appShortcuts 数组中
- 尝试更简单的短语(理想长度为 3-6 个词)
- 避免复杂语法或生僻词
测试 Spotlight 发现
- 向下轻扫以打开 Spotlight
- 输入你的 App 名称或快捷指令短语
- 验证快捷指令是否出现在结果中
- 轻点以执行
如果快捷指令没有出现在 Spotlight 中:
- 等待几分钟(索引可能需要时间)
- 重启设备
- 检查“系统设置” →“Siri 与搜索”→ [你的 App] →“在搜索中显示 App”
使用控制台日志调试
#if DEBUG
struct CoffeeAppShortcuts: AppShortcutsProvider {
@AppShortcutsBuilder
static var appShortcuts: [AppShortcut] {
let shortcuts = [
AppShortcut(/* ... */),
// ...
]
print("📱 Registered \(shortcuts.count) App Shortcuts")
shortcuts.forEach { shortcut in
print(" - \(shortcut.shortTitle)")
}
return shortcuts
}
}
#endif
App 启动后检查 Xcode 控制台,确认快捷指令已注册。
最佳实践
1. 短语设计
❌ 不要:使用冗长、复杂的短语
phrases: [
"I would like to order a coffee from \(.applicationName) please"
]
✅ 应该:使用简短、自然的短语
phrases: [
"Order coffee in \(.applicationName)",
"Get coffee from \(.applicationName)"
]
指南:
- 理想长度为 3-6 个词
- 以动词开头(订购、开始、获取、显示)
- 加入
\(.applicationName)以消除歧义 - 使用用户实际会说的自然语言
2. 快捷指令数量
❌ 不要:提供 20 个以上的快捷指令
// Bad: Overwhelming
AppShortcut for every possible combination
✅ 应该:专注于 3-5 个核心操作
// Good: Focused on common tasks
AppShortcut(intent: OrderIntent(), /* ... */)
AppShortcut(intent: ReorderIntent(), /* ... */)
AppShortcut(intent: ViewOrdersIntent(), /* ... */)
原因 快捷指令太多会显得杂乱。应专注于价值高、使用频繁的操作。
3. 参数组合
❌ 不要:为每种变体都设置参数
// Bad: Creates 12 shortcuts (3 sizes × 4 types)
for size in CoffeeSize.allCases {
for type in CoffeeType.allCases {
AppShortcut(intent: OrderIntent(type: type, size: size), /* ... */)
}
}
✅ 应该:提供通用选项以及 2-3 个最常见的选项
// Good: Generic + common specific cases
AppShortcut(intent: OrderIntent(), /* ... */) // Generic
AppShortcut(intent: OrderIntent(type: .latte, size: .medium), /* ... */) // Usual
AppShortcut(intent: OrderIntent(type: .espresso, size: .small), /* ... */) // Quick
4. 简短标题
❌ 不要:使用冗长或重复的标题
shortTitle: "Order Coffee from Coffee App"
✅ 应该:简洁明了
shortTitle: "Order"
说明 “快捷指令”App 中已经显示了 App 名称,因此无需重复。
5. 系统图像
❌ 不要:使用自定义图像
// Not supported
shortImage: UIImage(named: "custom")
✅ 应该:使用 SF Symbols
systemImageName: "cup.and.saucer.fill"
原因 SF Symbols 会正确缩放、支持深色模式,并能与系统 UI 集成。
资源
WWDC:2022-10170、2022-10169、260
文档:/appintents/appshortcutsprovider、/appintents/appshortcut、/appintents/app-shortcuts
技能:axiom-app-intents-ref、axiom-app-discoverability、axiom-core-spotlight-ref
请记住 App Shortcuts 能让用户在 iOS 中即时使用 App 的功能。定义 3-5 个带有自然短语的核心快捷指令,在 UI 中通过 SiriTipView 推广它们,用户便能立即通过 Siri、Spotlight、操作按钮等方式调用。