Apple Intelligence 时代:现代 App Intents 架构改造与 Spotlight 联动
从旧版 SiriKit 痛点出发,深入解析现代化 App Intents 框架的实体建模(AppEntity)、语义检索(EntityQuery)与零样本动作路由机制,重构面向 Apple Intelligence 的系统级接入层。
Apple Intelligence 时代:现代 App Intents 架构改造与 Spotlight 联动
TL;DR:随着 Apple Intelligence 在 iOS 18 及后续系统中的全面落地,Siri 与系统的语义入口发生了代际变革。过去基于
.intentdefinition图形化文件的 SiriKit 时代彻底谢幕,取而代之的是纯 Swift 代码声明、强类型编译期校验的 App Intents 框架。App 不再只是一个等待用户手动点击打开的孤岛,而是通过暴露AppEntity与AppIntent,成为系统级智能调度的分布式能力单元。本文分享如何对既有工程进行现代化改造,实现丝滑的 Spotlight 与自然语言意图直达。
一、 为什么旧版 SiriKit 无法支撑现代 AI 体验?
在旧版 SiriKit 架构下,开发者必须在 Xcode 里维护一个沉重的 .intentdefinition XML 配置文件,系统仅支持预设的十几个固定领域(如 VoIP 通话、打车、发消息):
- 类型安全性脆弱:生成的 Objective-C/Swift 桥接代码充斥着隐式解包可选型(IUO),一旦模型参数不匹配容易崩溃。
- 缺乏状态感知力:系统无法获知 App 当前内部的数据实体(如文档、音频片段、订单列表)具体有哪些,无法支持诸如“打开上周二李工发我的那份采购合同”等上下文模糊查询。
- 维护成本极高:每次新增动作都要跨多层文件同步,与现代 Swift 并发及声明式架构格格不入。
二、 现代核心模型:AppEntity 与 EntityQuery
现代架构的核心基石是将 App 内部的业务模型,抽象投影为符合系统契约的 AppEntity:
flowchart LR
subgraph App_Domain["App 领域实体"]
Model[ProjectDocument 业务模型]
end
subgraph Entity_Bridge["App Intents 抽象层"]
Entity[AppEntity 协议实现]
Query[EntityQuery 语义查询提供者]
Intent[OpenDocumentIntent 动作]
end
subgraph System_Surfaces["Apple Intelligence 系统级入口"]
Siri[Siri 自然语言理解]
Spotlight[Spotlight 语义索引搜索]
Shortcuts[快捷指令自动化]
end
Model --> Entity
Entity --> Query
Query --> System_Surfaces
System_Surfaces --> Intent
Intent -->|触发执行| Model
实体声明实战代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
import AppIntents
import CoreSpotlight
// 1. 业务实体声明
public struct ProjectDocumentEntity: AppEntity {
public static var defaultQuery = ProjectDocumentQuery()
public static var typeDisplayRepresentation: TypeDisplayRepresentation = "工程设计文档"
public var id: UUID
@Property(title: "文档标题")
public var title: String
@Property(title: "最后修改时间")
public var lastModifiedDate: Date
public var displayRepresentation: DisplayRepresentation {
DisplayRepresentation(
title: "\(title)",
subtitle: "修改于 \(lastModifiedDate.formatted(date: .abbreviated, time: .shortened))"
)
}
}
// 2. 实体查询检索器(支持系统高效检索)
public struct ProjectDocumentQuery: EntityQuery {
public init() {}
// 根据系统传入的 ID 批量获取实体
public func entities(for identifiers: [UUID]) async throws -> [ProjectDocumentEntity] {
let storage = await DocumentDatabase.shared
return try await storage.fetchDocuments(with: identifiers).map { $0.toEntity() }
}
// 供 Spotlight 和 Siri 在用户输入模糊关键词时调用
public func suggestedEntities() async throws -> [ProjectDocumentEntity] {
let storage = await DocumentDatabase.shared
return try await storage.fetchRecentDocuments(limit: 5).map { $0.toEntity() }
}
}
三、 零样本动作:实现可组合的 AppIntent
定义好数据实体后,执行具体动作的 AppIntent 变得极其简洁而确定:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public struct ExportDocumentAsPDFIntent: AppIntent {
public static var title: LocalizedStringResource = "将文档导出为 PDF"
public static var description = IntentDescription("将选定的工程设计文档渲染并导出为高保真 PDF 文件")
// 系统会自动通过 ProjectDocumentQuery 解析用户提及的实体
@Parameter(title: "目标文档")
public var targetDocument: ProjectDocumentEntity
@Parameter(title: "包含附件批注", default: true)
public var includeAnnotations: Bool
public init() {}
@MainActor
public func perform() async throws -> some ReturnsValue<URL> & ShowsSnippetView {
// 1. 获取底层真实数据
let doc = try await DocumentDatabase.shared.find(targetDocument.id)
// 2. 执行核心渲染导出
let pdfUrl = try await PDFExportEngine.render(document: doc, includeAnnotations: includeAnnotations)
// 3. 返回执行结果并展示原生交互卡片
return .result(
value: pdfUrl,
view: DocumentExportPreviewCard(document: doc, pdfUrl: pdfUrl)
)
}
}
四、 性能门禁与内存纪律
Apple Intelligence 对 Intent 的执行有着极其严苛的物理限制:
- 响应时间门禁($\le 500 ext{ ms}$):如果
perform()方法在 500ms 内没有完成初始化或返回异步句柄,系统会判定 App 无响应并向用户报出超时错误。因此耗时的重型计算必须立即将任务移交至后台 Worker。 - 内存上限($30 ext{ MB}$ 约束):当 Intent 作为独立的 App Extension 进程拉起时,系统为其分配的 Jetsam 内存上限极低,严禁在 Extension 内一次性解码超大原始图像。
五、 架构演进总结
App Intents 不仅是 Siri 的外挂,更是现代 iOS 应用模块化解耦的终极推手。将核心业务逻辑收敛为一个个纯粹、独立的 Intent 和 Entity,不仅让应用在系统级智能交互中占据先机,更让工程本身的单元测试与架构边界获得了前所未有的清晰度。
相关阅读与主题延伸
This post is licensed under CC BY 4.0 by the author.
