AppIntent — Apple 框架,在 iOS 16 中引入作为已过时的 Intents framework 的替代品,提供应用程序与 Siri、Shortcuts 和 Spotlight 集成的声明式 API。与旧方法(需要单独的 Intent Definition File 和生成 ObjC 代码)不同,AppIntent 使用纯 Swift 以及 AppIntent 和 AppEnum 协议。根据 Apple Developer Documentation, 2026,AppIntent 比 Intents framework 平均减少 60% 的代码量来创建一个 Intent,并且 Siri 指令的集成时间从几天缩短到几小时。
主要观点
AppIntent — Apple 框架,用于声明式描述您的应用程序可以基于 Siri、Shortcuts、Spotlight、Control Center 和 Action Button 的请求执行的指令。其基础是 AppIntent 协议,开发者在其中描述 Intent 的名称、参数和 perform() 方法——执行的逻辑。该框架自动生成用于在 Shortcuts 应用程序中配置参数的用户界面以及用于 Siri 的语音短语。
在 AppIntent 出现之前,开发者使用 Intents framework — 基于 Intent Definition File 的系统,生成 Objective-C 代码并需要配置单独的 Intents Extension。该过程复杂:即使一个简单的 Intent 也需要最多 5 个配置文件。AppIntent 消除了这种复杂性——Intent 在一个 Swift 文件中描述,系统自动生成与 Siri 和 Shortcuts 集成所需的一切。
根据 WWDC 2024 Session “Dive deeper into App Intents”,Apple 将 AppIntent 视为在传统界面之外扩展应用程序功能的核心机制。在 iOS 18 发布时,App Store 前 100 名应用程序中超过 70% 已经使用 AppIntent 与 Shortcuts 和 Siri 集成,平均每个 iOS 18 用户每天通过语音指令或小组件启动 4–6 个 Intent。
Intents framework (iOS 10–15) 需要创建 .intentdefinition 文件,通过 Xcode 生成 ObjC/Swift 类,配置 Intents Extension 和 App Intent Configuration。AppIntent (iOS 16+) 完全替代了这个流程,使用纯 Swift 代码,无需生成、扩展和额外配置。这使得创建 Intent 的过程对普通的 iOS 开发者而言更加容易,无需学习 SiriKit。
AppIntent 的主要优势在于其声明式特点。开发者描述 Intent 做什么,而不是它如何与系统集成。该框架自己处理 Siri 对话场景、在 Shortcuts 中显示参数以及在 Intent 之间传递上下文。在旧的 Intents framework 中,集成的每个方面都必须手动编码,包括用于显示 Intent UI 的 INUIHostedView。
| 特性 | Intents framework | AppIntent |
|---|---|---|
| 代码量 | 每个 Intent 100–300 行 | 30–60 行 |
| 所需文件 | .intentdefinition、Extension、Config | 1 个 Swift 文件 |
| 代码生成 | 必须(Xcode -> ObjC) | 不需要 |
| 异步性 | 仅支持 completion handler | async/await + 进度 |
| IntentDialog | 无 | 内置 Siri 对话 |
AppIntent — 定义 Intent 的核心协议。它包含 title(用于 Siri 的名称)、description(在 Shortcuts 中的描述)、参数(通过 @Parameter)和返回 IntentResult 的 perform() 方法。结果可以是 IntentDialog(与 Siri 的对话)、返回给 Shortcuts 的值或错误。每个 Intent 还可以提供 suggestedInvocationPhrase — 用于语音调用的短语。
AppEntity 描述 Intent 处理的实体。例如,如果应用程序管理项目,AppEntity Project 包含 id、displayRepresentation(如何在 UI 中显示实体)和 defaultQuery(如何搜索实体)。AppEnum — 用于选择参数的枚举,自动在 Shortcuts 中生成带有选择器元素的 UI。不需要手动创建参数列表,只需声明一个符合 AppEnum 的枚举即可。
enum TaskPriority: String, AppEnum {
case low, medium, high
static var typeDisplayRepresentation: TypeDisplayRepresentation =
"Priority"
var displayRepresentation: DisplayRepresentation {
switch self {
case .low: "Low"
case .medium: "Medium"
case .high: "High"
}
}
}
struct CreateTaskIntent: AppIntent {
static var title: LocalizedStringResource = "Create Task"
@Parameter(title: "Task Name")
var taskName: String
@Parameter(title: "Priority")
var priority: TaskPriority
func perform() async throws -> some IntentResult {
try await TaskManager.shared
.createTask(name: taskName, priority: priority)
return .result(dialog: "Task created")
}
}
AppIntent 的参数通过属性包装器 @Parameter 声明,该包装器自动与 Shortcuts UI 和 Siri 语音请求集成。每个参数都有一个 title(在 Shortcuts 中显示),并可以包含描述、默认值、限制。AppIntent 支持标准类型:String、Int、Double、Bool,以及通过 AppEntity 和 AppEnum 的自定义类型。
参数验证在 perform() 方法中在执行逻辑之前进行。如果参数不正确,Intent 通过 IntentError 返回错误。对于复杂验证,可以实现 validate() 方法,该方法在 perform() 之前调用,并可以在执行指令之前通过 IntentDialog 向用户提供反馈。这在 Siri 语音场景中尤其有用,因为重新询问用户比执行错误指令更容易。
struct SendMessageIntent: AppIntent {
static var title: LocalizedStringResource = "Send Message"
@Parameter(title: "Recipient")
var recipient: String
@Parameter(title: "Message")
var message: String
func validate() throws {
guard message.count >= 1 else {
throw IntentError.invalidMessage
}
}
func perform() async throws -> some IntentResult {
try await Messenger.shared
.send(recipient: recipient, text: message)
return .result(dialog: "Sent!")
}
}
一个完整的在应用程序中搜索笔记的 Intent 示例展示了与 AppEntity 和 EntityQuery 的工作。SearchNotesIntent 接收搜索字符串并返回找到的笔记列表。AppEntity Note 描述笔记的结构,EntityQuery 实现在存储中的搜索。结果通过带有实体数组的 IntentResult 返回,Shortcuts 将其显示给用户。
struct Note: AppEntity {
let id: UUID
let title: String
let content: String
static var typeDisplayRepresentation: TypeDisplayRepresentation =
"Note"
var displayRepresentation: DisplayRepresentation {
DisplayRepresentation(title: "(title)")
}
}
struct SearchNotesIntent: AppIntent {
static var title: LocalizedStringResource = "Search Notes"
@Parameter(title: "Query")
var query: String
func perform() async throws -> some IntentResult {
let results = await NoteStore.shared
.search(query)
.map { $0.toEntity() }
return .result(value: results)
}
}
声明 AppIntent 后,与 Shortcuts 和 Siri 的集成自动进行。Shortcuts 应用程序扫描已安装应用程序中的所有 AppIntent,并将其显示在可用操作列表中。用户可以将 Intent 添加到其指令中,配置其参数并与其他操作组合。对于 Siri,Intent 作为语音指令出现,无需开发者进行额外配置。
开发者可以通过添加 suggestedInvocationPhrase — 用于语音调用的推荐短语来改善集成。例如,对于添加任务的 Intent:suggestedInvocationPhrase = "Add new task"。Siri 分析该短语,并在学习语音指令时将其提供给用户。还可以指定 categories — Intent 的类别(create、view、search、edit),这有助于 Shortcuts 按意义将操作分组。
| 类别 | 示例 | 在 Shortcuts 中的行为 |
|---|---|---|
| .create | CreateTaskIntent | 与其他创建操作分组 |
| .view | ViewWeatherIntent | 显示在“查看”类别中 |
| .search | SearchNotesIntent | 标记为搜索操作 |
| .edit | UpdateTaskIntent | 与编辑操作分组 |
常见问题
不需要。AppIntent 不需要单独的 Intents Extension。Intent 直接编译到主应用程序中,这简化了架构并消除了进程间通信的需要。
AppIntent 可用于 iOS 16+、iPadOS 16+、macOS 13+、watchOS 9+。对于 iOS 15 及更早版本,需要使用 Intents framework。建议同时支持两种 API 以覆盖更多设备。
IntentsResult 支持 String、Int、Double、Bool、AppEntity 数组、IntentDialog 和自定义类型。复杂数据结构通过 EntityQuery 返回,该查询自动与 Shortcuts UI 集成。
可以,通过 AppIntentsPackage — 一个允许在服务器端执行 Intent 的包。对于具有服务器逻辑的应用程序很有用,在这种情况下 Intent 需要访问本地无法获取的数据。
使用带有 Shortcuts 应用程序的 iOS 16+ 模拟器。在模拟器上将 Intent 添加到 Shortcuts 指令中并运行。Siri 场景需要真实设备,因为模拟器不支持语音输入。
总结
我们将开发一款交钥匙移动应用程序
IT Sectr自2017年以来为初创企业和企业打造iOS和Android应用程序。我们将为您提供咨询并提出最佳解决方案。