前言:让应用与系统深度融合

在macOS 13 Ventura中,Apple引入了全新的App Intents框架,取代了旧版的SiriKit和Intents框架。App Intents让应用的核心功能可以暴露给系统,从而实现与Siri、快捷指令(Shortcuts)、聚焦搜索(Spotlight)和小组件(Widget)的深度集成。对于黑苹果用户而言,App Intents框架完全基于CPU计算,不依赖特定硬件,所有功能都可以正常运行。

本文将从App Intents的基础概念出发,逐步构建一个完整的应用集成方案,涵盖AppEntity定义、自定义Intent实现、语音指令配置和快捷指令深度集成。

一、App Intents框架架构

1.1 从SiriKit到App Intents的演进

Apple的意图(Intent)框架经历了三个阶段的演进:

  • SiriKit (2016):基于.plist定义的Intent,仅支持预定义的域名(消息、打车等),使用IntentHandler类
  • Intents UI (2018):增加了自定义UI,但仍受限于预定义域名
  • App Intents (2022):完全代码定义,支持任意自定义Intent,Swift原生API,与Shortcuts深度集成

App Intents的最大突破是允许开发者定义任意类型的Intent,不再受限于Apple预定义的域名。

1.2 核心协议与类型

协议/类型用途说明
AppIntent定义操作应用可以执行的动作(如"发送消息")
AppEntity定义数据类型应用的核心数据模型(如"任务"、"笔记")
EntityQuery查询实体让Siri和Shortcuts搜索和选择实体
AppShortcutsProvider注册快捷指令自动为应用创建快捷指令
IntentParameter定义参数Intent的输入参数(如"收件人"、"内容")

二、定义AppEntity

2.1 创建核心数据实体

AppEntity是App Intents的基础,它定义了你的应用中有意义的对象类型:

class Task: AppEntity {
    static var typeDisplayRepresentation = TypeDisplayRepresentation(name: "任务")
    static var defaultQuery = TaskQuery()
    
    var id: UUID
    var title: String
    var isCompleted: Bool
    var dueDate: Date?
    var priority: TaskPriority
    
    // 显示信息
    var displayRepresentation: DisplayRepresentation {
        DisplayRepresentation(
            title: "\(title)",
            subtitle: "\(isCompleted ? "已完成" : "进行中")"
        )
    }
    
    init(id: UUID = UUID(), title: String, isCompleted: Bool = false, 
         dueDate: Date? = nil, priority: TaskPriority = .medium) {
        self.id = id
        self.title = title
        self.isCompleted = isCompleted
        self.dueDate = dueDate
        self.priority = priority
    }
}

enum TaskPriority: String, AppEnum {
    case low = "低"
    case medium = "中"
    case high = "高"
    
    static var typeDisplayRepresentation = TypeDisplayRepresentation(name: "优先级")
    static var caseDisplayRepresentations: [TaskPriority: DisplayRepresentation] = [
        .low: "低优先级",
        .medium: "中优先级",
        .high: "高优先级"
    ]
}

2.2 实现EntityQuery

EntityQuery让Siri和Shortcuts能够搜索和选择你的实体:

struct TaskQuery: EntityQuery {
    func entities(for identifiers: [UUID]) async throws -> [Task] {
        // 根据ID查找任务
        return TaskStore.shared.tasks.filter { identifiers.contains($0.id) }
    }
    
    func suggestedEntities() async throws -> [Task] {
        // 返回建议的实体列表
        TaskStore.shared.tasks.filter { !$0.isCompleted }
    }
    
    func defaultResult() async -> Task? {
        // 默认选择
        TaskStore.shared.tasks.first { !$0.isCompleted }
    }
}

三、自定义AppIntent实现

3.1 创建任务Intent

struct CreateTaskIntent: AppIntent {
    static var title: LocalizedStringResource = "创建任务"
    static var description = IntentDescription("在任务管理器中创建一个新任务")
    static var openAppWhenRun: Bool = false
    
    @Parameter(title: "任务标题", inputOptions: String.IntentInputOptions(
        keyboardType: .default,
        autocorrect: true,
        capitalizeCharacters: .sentences
    ))
    var taskTitle: String
    
    @Parameter(title: "优先级", default: TaskPriority.medium)
    var priority: TaskPriority
    
    @Parameter(title: "截止日期")
    var dueDate: Date?
    
    @Dependency
    var taskStore: TaskStore
    
    func perform() async throws -> some IntentResult & ReturnsValue<Task> {
        let task = Task(
            title: taskTitle,
            priority: priority,
            dueDate: dueDate
        )
        taskStore.add(task)
        
        return .result(
            value: task,
            dialog: "已创建任务「\(taskTitle)」"
        )
    }
}

3.2 完成任务Intent

struct CompleteTaskIntent: AppIntent {
    static var title: LocalizedStringResource = "完成任务"
    static var description = IntentDescription("将指定任务标记为已完成")
    
    @Parameter(title: "任务")
    var task: Task
    
    func perform() async throws -> some IntentResult {
        task.isCompleted = true
        TaskStore.shared.update(task)
        
        return .result(dialog: "任务「\(task.title)」已完成")
    }
}

3.3 搜索任务Intent

struct SearchTasksIntent: AppIntent {
    static var title: LocalizedStringResource = "搜索任务"
    static var description = IntentDescription("按关键词搜索任务")
    
    @Parameter(title: "搜索关键词")
    var keyword: String
    
    @Parameter(title: "包含已完成", default: false)
    var includeCompleted: Bool
    
    func perform() async throws -> some IntentResult & ReturnsValue<[Task]> {
        var results = TaskStore.shared.tasks.filter { task in
            task.title.localizedCaseInsensitiveContains(keyword)
        }
        if !includeCompleted {
            results = results.filter { !$0.isCompleted }
        }
        
        return .result(
            value: results,
            dialog: "找到\(results.count)个匹配的任务"
        )
    }
}

四、AppShortcutsProvider注册

4.1 自动注册快捷指令

通过AppShortcutsProvider,你的应用安装后自动在快捷指令App中出现可用的动作:

struct TaskManagerShortcuts: AppShortcutsProvider {
    static var appShortcuts: [AppShortcut] {
        AppShortcut(
            intent: CreateTaskIntent(),
            phrases: [
                "在\(.applicationName)中创建任务",
                "用\(.applicationName)新建任务",
                "添加任务到\(.applicationName)"
            ],
            shortTitle: "创建任务",
            systemImageName: "plus.circle.fill"
        )
        
        AppShortcut(
            intent: CompleteTaskIntent(),
            phrases: [
                "在\(.applicationName)中完成任务",
                "用\(.applicationName)标记完成"
            ],
            shortTitle: "完成任务",
            systemImageName: "checkmark.circle.fill"
        )
        
        AppShortcut(
            intent: SearchTasksIntent(),
            phrases: [
                "在\(.applicationName)中搜索任务",
                "用\(.applicationName)查找任务"
            ],
            shortTitle: "搜索任务",
            systemImageName: "magnifyingglass"
        )
    }
    
    static var shortcutTileColor: ShortcutTileColor {
        .blue
    }
}

五、与快捷指令App深度集成

5.1 构建自动化工作流

用户可以在快捷指令App中将你的Intent与其他系统的Intent组合,创建强大的自动化工作流。例如:

  • 收到特定邮件 → 自动创建任务
  • 日历事件开始前 → 搜索相关任务并提醒
  • 到达公司 → 搜索高优先级未完成任务
  • 定时(每天早上9点)→ 搜索今日到期任务并发送通知

5.2 Focus Filter集成

App Intents还可以与Focus模式集成,实现基于专注模式的内容过滤:

struct TaskFocusFilter: SetFocusFilterIntent {
    static var title: LocalizedStringResource = "任务过滤"
    static var description = IntentDescription("根据专注模式过滤显示的任务")
    
    @Parameter(title: "仅显示高优先级", default: false)
    var showHighPriorityOnly: Bool
    
    var displayRepresentation: DisplayRepresentation {
        DisplayRepresentation(
            title: "任务过滤: \(showHighPriorityOnly ? "仅高优先级" : "全部")"
        )
    }
}

六、黑苹果环境注意事项

6.1 Siri可用性

在黑苹果上,Siri功能通常可以正常使用,但需要:

  • 正确的SMBIOS配置(推荐iMac20,1或MacPro7,1机型)
  • 有效的Apple ID登录
  • 麦克风正常工作(AppleALC正确配置输入设备)

6.2 快捷指令App兼容性

快捷指令(Shortcuts)App完全基于软件实现,在黑苹果上没有硬件限制。所有功能包括:

  • 创建和运行自定义快捷指令
  • 个人自动化(时间触发、App触发等)
  • 与第三方App的Intent集成
  • 在菜单栏中显示快捷指令

6.3 调试技巧

在黑苹果上调试App Intents时的注意事项:

  • 使用Xcode的Shortcuts App调试目标运行和测试Intent
  • 在终端使用shortcuts run命令行运行快捷指令进行调试
  • 查看Console.app中的App Intents相关日志
  • 如果Intent没有出现在快捷指令中,检查AppShortcutsProvider是否正确注册

总结

App Intents框架代表了macOS应用集成的未来方向。通过定义AppEntity和AppIntent,你的应用可以与Siri、快捷指令、聚焦搜索和小组件深度集成,极大提升了用户体验和操作效率。在黑苹果环境下,App Intents的所有核心功能都可以正常运行,关键是确保SMBIOS配置正确以获得完整的Siri支持。

建议从简单的CRUD Intent开始实践,逐步添加EntityQuery、Focus Filter等高级特性,最终构建出与系统深度融合的专业级应用。

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。