用 App Intents 把应用核心功能带到用户面前
Bring your app's core features to users with App Intents
2024年6月10日
一句话判断
App Intents 不是某一个功能,而是 Siri、Spotlight、Shortcuts、Widgets、Control Center 等全系系统体验的统一底座——写一次 Intent,你的应用功能就能渗透到设备的每个角落。
这场 Session 讲了什么
这场 Session 是 App Intents 的入门总览,面向还没有接触过这个框架的开发者。主讲人 Christopher Nebel 用一个徒步路线 App 做贯穿全场的 demo,展示了如何让你的应用功能不再困在”方块图标”里。
核心理念是”减少摩擦”(friction)。用户在多个 App 之间切换本身就是一种摩擦。如果系统能理解你 App 里的核心动作和内容,就可以把它们直接展示在 Spotlight、Siri、Widget、Control Center 里,用户不需要打开你的 App 就能完成操作。App Intents 就是实现这一切的统一协议层——你定义好 Intent(动作)、Entity(对象)、App Shortcut(预设快捷方式),系统各处就能自动消费这些定义。
Session 的后半段演示了具体实现:从定义一个 OpenTrailIntent 到让它在 Spotlight Suggestions 中出现,再到用 Entity 让 Siri 理解”我的收藏路线”这类自然语言指令。整个过程不需要为每个系统功能写单独的集成代码,App Intents 做了统一的通信管道。
值得深挖的点
App Intents 的三层抽象:Intent、Entity、App Shortcut
这三个概念构成了一个类似”动词-名词-句子”的语法体系。Intent 是动词,比如”打开路线”或”开始徒步”。Entity 是名词,比如”路线”或”合集”。App Shortcut 则是把动词和名词打包成一句话,代表你 App 里最核心的功能。
这种设计的精妙之处在于复用性。你定义一个 TrailEntity,所有需要引用路线的 Intent 都能共享它。你定义一个 OpenTrailIntent,它在 Spotlight、Siri、Shortcuts 里都能被触发。过去开发者要分别对接 SiriKit、NSUserActivity、CSSearchableItem 等不同 API,现在一套代码覆盖所有场景。
Trade-off 也很明显:App Intents 要求你用 Swift 的 @AssistantIntent 宏来声明式地定义意图,这套 DSL 有学习曲线,而且编译时的类型检查会比较严格。但换来的是跨场景的零成本复用,以及 Apple Intelligence 时代 Siri 对你 App 内容的深度理解。
“Flow” 的设计哲学
Session 反复强调 flow(心流)这个概念,不只是心理学层面的”沉浸感”,更是设备层面的”最小路径”。用户想到一件事到完成这件事之间的步骤越少,体验就越好。App Intents 让你的 App 不再是一个孤岛,而是变成设备体验的一部分。对于用户粘性来说,这意味着用户不需要”进入”你的 App 才能感受到它的价值——Widget 展示实时信息、Spotlight 快捷操作、Siri 语音指令,都在持续强化你和用户之间的连接。
代码片段
定义一个简单的 App Intent
struct OpenTrailIntent: AppIntent {
static var title: LocalizedStringResource = "Open Trail"
static var description = IntentDescription("Opens a specific trail in the app")
@Parameter(title: "Trail")
var trail: TrailEntity
func perform() async throws -> some IntentResult {
// 导航到指定路线的详情页
Navigator.shared.open(trail)
return .result()
}
}
一句话说明:这是最基本的 Intent 定义,@Parameter 让 Siri 知道需要用户提供哪个路线,perform() 是实际执行逻辑。坑在于 title 必须用 LocalizedStringStringResource,普通的 String 不行。
定义 Entity 让系统理解你的数据模型
struct TrailEntity: AppEntity {
static var typeDisplayRepresentation = TypeDisplayRepresentation(name: "Trail")
static var defaultQuery = TrailEntityQuery()
var id: UUID
var name: String
var difficulty: TrailDifficulty
var displayRepresentation: DisplayRepresentation {
DisplayRepresentation(title: "\(name)")
}
}
一句话说明:Entity 是你的数据模型在系统层面的投影,defaultQuery 负责让 Siri 能搜索和匹配你的数据。别忘了实现 EntityQuery,否则 Siri 无法解析用户说的”那条我收藏的路线”。
注册 App Shortcut 让功能出现在 Spotlight
struct TrailShortcuts: AppShortcutsProvider {
static var appShortcuts: [AppShortcut] {
AppShortcut(
intent: OpenTrailIntent(),
phrases: [
"Open \(.applicationName)",
"Show my trail in \(.applicationName)"
],
shortTitle: "Open Trail",
systemImageName: "figure.hiking"
)
}
}
一句话说明:phrases 数组定义了 Siri 语音触发短语,也是 Spotlight Suggestions 展示的依据。短语要尽量口语化,不要写技术术语。
最佳实践
新项目:从第一天就把 App Intents 纳入架构设计。数据模型直接用 AppEntity 协议来定义,核心操作用 AppIntent 封装。这样你在做 Widget、Control Center 扩展时几乎零额外成本。
已有项目:不要试图一次迁移所有功能。先挑 1-2 个最高频操作(比如”打开最近使用的文档”、“标记收藏”),把它们做成 App Shortcut。这些最容易在 Spotlight 和 Siri 中暴露给用户,立竿见影。之后再逐步扩展 Entity 和 Intent 的覆盖范围。
两个通用原则:第一,App Shortcut 的数量不要贪多,每个 Shortcut 应该是你 App 的核心价值入口;第二,Entity 的 displayRepresentation 要花时间打磨,它直接决定了 Siri 向用户展示时的可读性。
还有什么值得关注
- Control Center 自定义控件今年也基于 App Intents,你的 Intent 加上
WidgetConfigurationIntent就能变成 Control Center 里的按钮。 - Action Button 和 Apple Pencil Pro 的 squeeze 手势同样消费 App Intents,硬件交互的软件层也是统一的。
- Apple Intelligence 的 Siri 重大升级底层就是依赖 App Intents 提供的结构化数据,越早接入,Siri 对你 App 的理解越深。