我们来详细了解一下 App Intents 框架与苹果的“专注模式”(Focus) 功能是如何结合的,这主要通过专注过滤器 (Focus Filters) 来实现。
一、专注模式 (Focus) 简述 #
首先,简单回顾一下什么是“专注模式”。这是苹果操作系统(iOS, iPadOS, macOS)中的一项功能,允许用户根据当前进行的活动(如工作、个人事务、睡眠、驾驶、健身等)自定义哪些应用和联系人可以通知他们,并可以定制主屏幕、锁定屏幕的布局。目的是帮助用户减少干扰,更好地专注于当前任务。
二、App Intents 与专注过滤器 (Focus Filters) #
- 是什么? 专注过滤器允许你的应用根据用户当前激活的专注模式来调整自身的内容显示和行为。你的应用可以定义一些自定义的过滤器,用户随后可以在“设置”App 中为特定的专注模式启用和配置这些来自你应用的过滤器。
- App Intents 如何参与? 你的应用通过定义一种特殊的
AppIntent
(或者说,是一个遵循特定模式的AppIntent
)来向系统提供这些自定义的过滤器及其可配置的参数。这个AppIntent
实际上定义了你的过滤器能接受哪些设置。
三、为什么使用 App Intents 来实现专注过滤器?(目的与优势) #
- 与专注模式深度集成: 让你的应用不仅仅是被专注模式简单地“允许通知”或“禁止通知”。应用可以主动感知到专注模式,并据此智能地调整内部状态或显示内容,提供更深层次的集成。
- 提升内容相关性: 根据用户当前的上下文(例如“工作”专注模式),应用可以筛选显示最相关的内容,屏蔽不相关的内容,从而变得更加实用。
- 用户高度自定义: 用户可以在系统“设置”中为每个专注模式选择启用哪些应用的过滤器,并对这些过滤器进行个性化配置(例如,在“工作”专注模式下,邮件应用只显示“工作邮箱”的邮件)。
- 减少干扰,提升专注度: 通过在应用内部过滤掉与当前专注模式不符的信息,帮助用户更好地保持专注。
- 应用主动适应: 应用不再是被动地被系统限制,而是可以主动地、优雅地适应用户的专注状态。
四、核心组件与概念 #
定义过滤器意图 (Filter
AppIntent
):- 你需要创建一个遵循
AppIntent
协议的struct
或class
。这个意图本身就代表了你的一个专注过滤器配置。 @Parameter
: 在这个意图中,你会使用@Parameter
来定义用户可以配置的选项。例如,一个邮件应用的过滤器意图可能有一个@Parameter
用于让用户选择要显示的邮件账户(类型可能是一个AppEntity
代表账户),或者一个@Parameter
让用户选择要屏蔽的标签(类型可能是一个AppEnum
或布尔值)。title
和description
: 像其他AppIntent
一样,你需要提供描述这个过滤器用途的title
和可选的description
。perform()
方法: 对于专注过滤器来说,perform()
方法可能不是主要部分,因为这个意图的核心作用是承载配置状态。但它仍然需要被实现,可以简单地返回.result()
。
- 你需要创建一个遵循
系统设置中的配置:
- 当你定义了这样的过滤器意图后,用户就可以在 设置 > 专注 > [选择一个专注模式] > 添加过滤器 > [你的应用名称] 中找到并添加你的过滤器。
- 系统会根据你过滤器意图中定义的
@Parameter
自动生成配置界面,供用户设置。
应用接收和响应过滤器状态:
- 当一个包含你的应用过滤器的专注模式被激活或停用时,系统会通知你的应用。
- 关键在于你的应用如何获取当前激活的过滤器配置(即用户为你的过滤器意图设置的参数值)。这通常通过以下方式实现:
FocusFilterManager
(非官方名称,指代一个处理逻辑的类): 你可能需要一个集中的地方来管理和响应专注模式的变化。- 查询当前状态: 当专注模式变化时,你的应用需要查询与当前激活的专注模式关联的、你的应用的过滤器配置。
- API (例如
AppFocusState
,FocusFilterContext
, 或通过 AppDelegate/SceneDelegate 回调): 系统会提供 API 让你的应用知道哪个过滤器配置(即你的哪个AppIntent
实例以及它的参数值)当前是激活的。 (具体的 API 名称和方式请查阅最新的苹果官方文档,因为这部分 API 细节可能随系统版本演进)。 - 核心思想是:系统保存了用户为每个专注模式配置的你的过滤器意图实例。当专注模式激活,你的应用可以获取到这个配置好的意图实例。
五、工作流程(高层次) #
应用定义过滤器意图 (Schema):
你的应用定义一个或多个 AppIntent,这些意图的结构(参数)定义了用户可以如何配置你的专注过滤器。
import AppIntents // 假设我们有一个 AppEntity 代表邮件账户 struct MailAccountEntity: AppEntity { /* ... */ } struct MailAccountFocusFilter: AppIntent { static var title: LocalizedStringResource = "Filter Mail by Account" static var description: IntentDescription? = "Shows emails only from the selected account." static var openAppWhenRun: Bool = false // 通常过滤器不需要打开App // 用户可以在专注模式设置中选择一个邮件账户 @Parameter(title: "Account to Show") var account: MailAccountEntity? // 可选,用户可能不选择任何特定账户 // perform() 对于专注过滤器意图,主要是为了满足 AppIntent 协议 // 实际的过滤逻辑在应用内部响应状态变化时执行 func perform() async throws -> some IntentResult { // 这个 perform 可能不会被直接“运行”来执行过滤 // 它的实例和参数值会被系统传递给你的应用 return .result() } }
系统发现意图:
系统会自动发现你的应用提供的这些用于专注过滤器的 AppIntent。
用户在系统设置中配置:
- 用户进入 设置 > 专注 > [某个专注模式]。
- 点击“添加过滤器”,选择你的应用。
- 系统会展示你的
MailAccountFocusFilter
(或你定义的其他过滤器意图)的配置界面,用户可以选择一个MailAccountEntity
作为account
参数的值。 - 这个配置(例如,“在‘工作’专注模式下,邮件过滤器选择‘work@example.com’账户”)会被系统保存。
专注模式激活:
当用户激活那个配置了你的过滤器的专注模式时(例如,“工作”专注模式):
- 系统会通知你的应用当前专注模式已更改,并且你的某个过滤器配置现在是激活状态。
- 你的应用需要获取到那个激活的
MailAccountFocusFilter
意图实例,特别是其中用户设置的account
参数值 (例如work@example.com
)。
应用调整行为和内容:
- 你的应用获取到配置(例如,只显示
work@example.com
的邮件)后,就应该相应地调整其数据源查询和 UI 显示。 - 例如,邮件列表现在只加载和显示来自指定账户的邮件。
- 你的应用获取到配置(例如,只显示
专注模式停用/过滤器移除:
当用户关闭该专注模式,或者从专注模式中移除了你的应用过滤器时,系统也会通知你的应用。你的应用应该恢复到正常的、未经过滤的状态。
六、使用场景示例 #
- 邮件应用:
- 过滤器:按账户显示邮件 (例如,工作专注模式只显示工作邮箱)。
- 过滤器:只显示来自特定联系人组的邮件。
- 信息应用:
- 过滤器:只显示来自允许列表联系人的信息。
- 过滤器:隐藏特定群聊的通知和内容。
- 日历应用:
- 过滤器:只显示工作日历,或只显示个人日历。
- 待办事项应用:
- 过滤器:只显示标记为“工作”的待办事项,或特定项目列表中的事项。
- 新闻/阅读应用:
- 过滤器:在“学习”专注模式下,只显示科技和教育类新闻。
- 社交媒体应用:
- 过滤器:在“个人”专注模式下,只显示来自“亲密好友”列表的动态。
- 过滤器:在“勿扰”专注模式下,完全隐藏动态推送,只允许查看已关注内容。
七、实现要点 (概念性) #
定义你的过滤器
AppIntent
: 这是第一步,明确你的应用可以提供哪些可配置的过滤维度。获取当前过滤器配置:
你需要在应用启动时或专注模式变化时,检查当前是否有你的过滤器处于激活状态,并获取其配置。
这可能涉及到监听系统通知(如
NotificationCenter
发布的专注模式变化通知),或者使用特定的 API 来查询当前激活的过滤器配置。苹果可能会提供一个代理方法(例如在
AppDelegate
或特定管理器中)来传递激活的过滤器AppIntent
实例。例如,类似这样的概念:// 这只是一个概念性的示例,具体 API 请查阅最新文档 // class MyAppFocusDelegate: NSObject, SomeFocusFilteringDelegate { // func focusFilterDidChange(activeFilter: MailAccountFocusFilter?) { // if let filter = activeFilter, let account = filter.account { // print("Focus filter active for account: \(account.name)") // // 更新应用的过滤状态 // } else { // print("No specific mail account filter active or focus changed.") // // 清除过滤状态 // } // } // }
应用内部实现过滤逻辑: 根据获取到的过滤器配置(即
AppIntent
的参数值),修改你的数据获取逻辑(例如,在数据库查询中加入WHERE account_id = ?
条件)和 UI 展示。响应过滤器停用: 当过滤器不再激活时,确保应用能够恢复到未过滤的状态。
通过 App Intents 实现专注过滤器,可以让你的应用变得更加智能和贴心,真正帮助用户在不同场景下高效地使用你的应用,同时保持专注。建议查阅最新的 Apple 开发者文档中关于 “Focus Filters” 和 “App Intents” 的部分,以获取最准确的 API 使用方法和实现细节。