SiriKit — 介绍
This article is extracted from the chat log with AI. Please identify it with caution.

🧠 什么是 SiriKit? #

SiriKit 是 Apple 在 iOS 10 引入的一套系统框架,允许你的 App 被 Siri 调用执行特定任务。它提供一组 “意图(Intent)”类别,比如:

  • 发送消息(Messages)

  • 创建待办(Tasks)

  • 支付(Payments)

  • 预订(RideBooking)

  • 健身(Workout)等

✅ SiriKit 的关键特性: #

特性说明
使用系统定义的 Intent 类比如 INSendMessageIntent
基于 Intents Extension必须创建 Intents Extension 处理器
配置复杂需要额外的目标和 plist 配置
被系统严重限制只能处理系统支持的 Intent 类型
用户交互有限不能完全定制化语义和体验

🚀 什么是 App Intents? #

App Intents 是 Apple 在 iOS 16+ 推出的新框架,目的是取代 SiriKit 的大部分能力,并同时支持:

  • Siri

  • Spotlight(搜索建议)

  • Shortcuts(快捷指令)

  • App Widgets(iOS 17 可交互 Widget)

  • App Shortcuts(无需用户手动创建快捷方式)

✅ App Intents 的优势: #

特性说明
100% Swift 实现使用 AppIntent 协议定义 Intent 类
支持参数输入自定义输入参数(枚举、文字、布尔等)
易于维护和扩展不再需要 Intents Extension
与 Widget 紧密集成可用于点击 Widget 执行操作
与 Siri 深度集成自定义短语就能被 Siri 唤起
可配置 UI 显示支持语义标签、分组、分类、权限控制等

🧩 App Intents 与 SiriKit 的关系 #

比较维度SiriKitApp Intents
引入版本iOS 10iOS 16
实现方式基于 Extension(Intents Extension)原生 Swift + 主 App 中实现
可扩展性固定模板 + 系统意图自定义完全自由
Siri 支持✅ 支持(仅限部分用例)✅ 完全支持 Siri
Spotlight 搜索✅ 支持自动补全与搜索
Widget/Live Activity 支持✅ 可与交互式 Widget/Live Activity 配合
使用复杂度高(需 Extension、plist)低(纯 Swift 实现)
推荐使用❌(仅用于遗留场景)✅(现代统一方式)

🔁 示例:从 SiriKit 到 App Intents 的进化 #

SiriKit 示例:用户说“发送信息给妈妈” #

你需要使用:

  • INSendMessageIntent

  • INSendMessageIntentHandling 协议

  • 创建 Intents Extension 并实现 resolveRecipients() 等方法

⚠️ 只能处理 Apple 支持的“发送信息”类场景


App Intents 示例:用户说“开始专注 25 分钟” #

你可以自定义:

struct StartTimerIntent: AppIntent {
    static var title: LocalizedStringResource = "开始计时"
    
    @Parameter(title: "类型")
    var type: TimerTypeEntity
    
    func perform() async throws -> some IntentResult {
        TimerManager.shared.start(type: type.toTimerType())
        return .result()
    }
}

用户说:“嘿 Siri,开始专注”
→ Siri 触发 StartTimerIntent → App 启动定时器


🔚 总结:什么时候用 SiriKit?什么时候用 App Intents? #

使用场景推荐技术
要处理系统预定义的特定语义(如打电话、发短信)✅ SiriKit
自定义任务(如计时器、记录、启动操作)✅ App Intents
为 Widget 添加交互操作✅ App Intents
为 Shortcuts 提供自动发现的快捷入口✅ App Intents
快速响应 Siri 自然语言命令✅ App Intents(更智能)

如果你正在开发的是一个现代 iOS 应用(尤其是支持 Siri、快捷指令、Widget 的),优先使用 App Intents。

可以说,SiriKit 正在被边缘化,但尚未完全过时。以下是详细解释:


🧓 SiriKit 的现状:正在被 App Intents 替代 #

✅ SiriKit 仍可用,但局限越来越明显: #

  • SiriKit 仍支持系统级任务(如发短信、打车、锻炼、CarPlay)

  • Apple 没有宣布废弃 SiriKit,但从 iOS 16 开始就几乎不再更新其功能

  • 文档中多次鼓励开发者转向 App Intents

  • 新功能(如 Widget 交互、Spotlight 搜索、App Shortcuts)完全不支持 SiriKit


📈 App Intents 是 SiriKit 的现代替代者 #

特性SiriKitApp Intents
系统级任务(如打车)✅ 强项❌ 无法取代
自定义任务 / 操作❌ 受限✅ 推荐方式
与 Widget 交互❌ 不支持✅ 深度整合
无需 Extension❌ 必须要✅ 直接 Swift 实现
多平台支持iOS/watchOS/macOS(有限)✅ 全面支持
快捷指令自动集成❌ 需要配置✅ 零配置自动曝光

📌 官方态度 #

虽然 Apple 没有宣布“废弃 SiriKit”,但以下信号很明显:

  • Xcode 模板默认引导使用 App Intents,而非 SiriKit

  • Apple 在 WWDC 2022 和 2023 中大力推广 App Intents

  • 快捷指令 / Widget / Spotlight / Siri 全部统一使用 App Intents 架构

  • 新文档几乎不再更新 SiriKit 的新能力


✅ 实践建议(2024–2025年): #

需求建议
发短信、打开地图、播放音乐等系统行为使用 SiriKit
启动自定义功能、计时器、记录、切换状态等使用 App Intents
面向未来(Siri、Widget、搜索等统一入口)构建在 App Intents 上

🧠 一句话总结: #

SiriKit 是过去的桥梁,App Intents 是现在和未来的高速路。


如果你在构建一个新项目,强烈推荐完全使用 App Intents 来取代你过去在 SiriKit 中想做的事情。
如果需要,我可以帮你将一个 SiriKit 场景“迁移”到 App Intents 的写法,看看效果对比?

示例 #

我们来实现一个完整可用的 Siri 命令 + AppIntent 示例:用户说「嘿 Siri,开始长休息」就能触发一个 长休息计时器(你也可以换成专注、短休息等)。


🧱 整体目标 #

  • 使用 Swift 实现 AppIntent

  • 支持 Siri 语音命令「开始长休息」

  • 启动你自己的倒计时逻辑

  • 支持 Widget、快捷指令、Spotlight 自动集成(自动展示,不用手动添加)


✅ 第一步:创建 TimerTypeEntity.swift #

enum TimerType: String, CaseIterable, Codable {
    case focus = "专注"
    case shortBreak = "短休息"
    case longBreak = "长休息"

    var duration: TimeInterval {
        switch self {
        case .focus: return 25 * 60
        case .shortBreak: return 5 * 60
        case .longBreak: return 15 * 60
        }
    }
}

如果你想让 Siri 能识别「长休息」「专注」,你还需要声明一个 AppEntity

import AppIntents

struct TimerTypeEntity: AppEntity, Identifiable, Hashable {
    let id: String
    let type: TimerType

    static var typeDisplayRepresentation: TypeDisplayRepresentation = "计时器类型"

    var displayRepresentation: DisplayRepresentation {
        DisplayRepresentation(title: "\(type.rawValue)")
    }

    static var defaultQuery = TimerTypeQuery()

    // 提供可选择列表
    struct TimerTypeQuery: EntityQuery {
        func entities(for identifiers: [String]) async throws -> [TimerTypeEntity] {
            TimerType.allCases
                .filter { identifiers.contains($0.rawValue) }
                .map { TimerTypeEntity(id: $0.rawValue, type: $0) }
        }

        func suggestedEntities() async throws -> [TimerTypeEntity] {
            TimerType.allCases.map { TimerTypeEntity(id: $0.rawValue, type: $0) }
        }
    }
}

extension TimerTypeEntity {
    func toTimerType() -> TimerType { type }
}

✅ 第二步:实现 AppIntent —— StartTimerIntent #

struct StartTimerIntent: AppIntent {
    static var title: LocalizedStringResource = "开始计时器"
    static var description = IntentDescription("开始一个指定类型的计时器")

    @Parameter(title: "计时器类型")
    var timerType: TimerTypeEntity

    static var openAppWhenRun: Bool = true // Siri 执行时是否打开 App

    func perform() async throws -> some IntentResult {
        let type = timerType.toTimerType()

        // 启动你的计时器逻辑
        TimerManager.shared.start(type: type)

        return .result(dialog: "已开始\(type.rawValue)计时")
    }
}

☝️ Siri 会自动读取 title + parameter,并且使用 displayRepresentation 自动生成语音命令。


✅ 第三步:让 App 支持 Siri / AppIntents #

你需要在你的 App 的 Info.plist 添加权限描述字段:

<key>IntentsSupported</key>
<array>
    <string>StartTimerIntent</string>
</array>

然后确认你的主 App(不是 Widget Extension)已经:

  • 添加了 AppIntents 框架

  • StartTimerIntent 放在主 App 中(不是 Widget 里)


✅ 第四步:调用计时器逻辑(例子) #

final class TimerManager {
    static let shared = TimerManager()

    func start(type: TimerType) {
        print("已开始 \(type.rawValue),持续 \(type.duration) 秒")
        // 实际可触发 Live Activity、通知等逻辑
    }
}

🗣️ Siri 调用演示 #

现在你可以直接对 iPhone 或 Simulator 说:

嘿 Siri,开始长休息

或使用 Spotlight 搜索「开始长休息」,或者进入快捷指令 app,AppIntent 会自动出现!


🚀 加强体验建议(可选) #

项目建议
添加 Widget 时用这个 AppIntent 做入口✅ 可点击 Widget 直接触发
添加 Live Activity 展示倒计时✅ 锁屏同步状态
添加语音反馈(dialog:✅ 已使用
添加 Siri Shortcuts 图标✅ 可在 Shortcut App 设置

✅ 总结 #

你现在已经完成一个完整 Siri 命令集成的 AppIntent 示例,实现了用自然语言指令启动自定义功能。
这就是 AppIntents 统一 Siri + Widget + Shortcuts 的强大之处。

Live Activity 效果 #

很好!我们在前面已经完成了 Siri + AppIntent 启动计时器,现在再加上 Live Activity,实现用户说“开始长休息”之后:

  1. 自动触发 Live Activity

  2. 在锁屏 / 动态岛 / 主屏上显示实时倒计时


🎯 整体结构 #

我们会加入以下内容:

  1. ActivityAttributes 定义计时器属性

  2. LiveActivityManager 启动 Live Activity

  3. 修改 TimerManager 在开始计时时启动 Live Activity

  4. DynamicIsland/锁屏 UI 更新


✅ 第一步:定义 TimerActivityAttributes #

import ActivityKit

struct TimerActivityAttributes: ActivityAttributes {
    public struct ContentState: Codable, Hashable {
        var endTime: Date
    }

    var title: String
}

title: 如「长休息」
endTime: 用于倒计时结束时间


✅ 第二步:创建 LiveActivityManager #

import ActivityKit

final class LiveActivityManager {
    static let shared = LiveActivityManager()
    private var currentActivity: Activity<TimerActivityAttributes>?

    func startActivity(for type: TimerType) {
        let endTime = Date().addingTimeInterval(type.duration)

        let attributes = TimerActivityAttributes(title: type.rawValue)
        let state = TimerActivityAttributes.ContentState(endTime: endTime)

        do {
            currentActivity = try Activity<TimerActivityAttributes>.request(
                attributes: attributes,
                contentState: state,
                pushType: nil
            )
        } catch {
            print("🚨 启动 Live Activity 失败: \(error)")
        }
    }

    func stopActivity() {
        Task {
            await currentActivity?.end(dismissalPolicy: .immediate)
        }
    }
}

✅ 第三步:修改 TimerManager 启动 Live Activity #

final class TimerManager {
    static let shared = TimerManager()

    func start(type: TimerType) {
        print("已开始 \(type.rawValue),持续 \(type.duration) 秒")
        LiveActivityManager.shared.startActivity(for: type)
    }
}

✅ 第四步:实现 Live Activity 的 UI(锁屏 & 动态岛) #

你需要在 Widget Extension 中添加:

TimerWidgetLiveActivity.swift #

import ActivityKit
import WidgetKit
import SwiftUI

struct TimerWidgetLiveActivity: Widget {
    var body: some WidgetConfiguration {
        ActivityConfiguration(for: TimerActivityAttributes.self) { context in
            // 锁屏 UI
            VStack {
                Text(context.attributes.title)
                    .font(.headline)
                CountdownView(to: context.state.endTime)
            }
            .padding()
        } dynamicIsland: { context in
            DynamicIsland {
                DynamicIslandExpandedRegion(.center) {
                    VStack {
                        Text(context.attributes.title)
                            .font(.headline)
                        CountdownView(to: context.state.endTime)
                    }
                }
            } compactLeading: {
                Text("⏱")
            } compactTrailing: {
                CountdownView(to: context.state.endTime)
                    .font(.caption)
            } minimal: {
                Text("⏱")
            }
        }
    }
}

添加倒计时视图组件 #

struct CountdownView: View {
    let to: Date
    @State private var now = Date()
    private let timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect()

    var body: some View {
        Text(remainingTime)
            .onReceive(timer) { _ in now = Date() }
    }

    var remainingTime: String {
        let diff = Int(to.timeIntervalSince(now))
        let m = diff / 60
        let s = diff % 60
        return String(format: "%02d:%02d", m, s)
    }
}

✅ 第五步:在 Widget Extension 中注册 Live Activity #

确保 @main 中包含:

@main
struct MyTimerWidgets: WidgetBundle {
    var body: some Widget {
        TimerWidgetLiveActivity()
        // 可添加普通 Widget 等
    }
}

✅ 权限设置 #

在主 App 的 Info.plist 添加:

<key>NSUserActivityTypes</key>
<array>
    <string>com.apple.activitykit.activity</string>
</array>

✅ 运行效果 #

  • 用户说:「嘿 Siri,开始长休息

  • Siri 启动 StartTimerIntent

  • 启动你的计时器逻辑 + Live Activity

  • 动态岛 / 锁屏 显示倒计时!


✅ Bonus:Live Activity 结束自动关闭 #

你可以用 DispatchQueue.main.asyncAfter 或计时器监听倒计时结束,调用:

LiveActivityManager.shared.stopActivity()
本文共 3326 字,创建于 May 22, 2025
相关标签: Xcode, ByAI, ChatGPT