System & Services 进阶 20m
认识 Focus 过滤器
Meet Focus filters
2022年6月6日
一句话判断
Focus filters 让你的应用能根据用户当前的专注模式自动调整行为——如果你做多账号、多日历或内容筛选类功能,这个 API 应该立刻排进排期。
这场 Session 讲了什么
iOS 16 和 macOS Ventura 为 Focus(专注模式)引入了 Focus Filters 机制。之前 Focus 只能控制系统层面的通知行为,现在它可以深入到每个应用的内部逻辑。
系统应用的示范很直观:
- 日历:Work Focus 时只显示工作日历,Personal Focus 时只显示个人日历
- 邮件:按 Focus 过滤收件箱和通知,只显示当前场景相关的邮件
- Safari:不同 Focus 使用不同的标签页组
开发者可以通过 SetFocusFilterIntent 协议让自己的应用也支持这种上下文感知。用户在系统设置的 Focus 配置界面中就能直接定制你的应用在不同 Focus 下的行为。
值得深挖的点
Focus Filter 的信息传递机制是整个框架的核心。你的应用定义一个 SetFocusFilterIntent,声明哪些参数可以被用户配置(比如”显示哪个账号”、“是否启用深色模式”)。系统在用户切换 Focus 时通过两种方式通知你的应用:
- 应用正在运行时,调用
perform()方法 - 应用不在运行时,通过 App Extension 接收通知
Display Representation 的动态生成决定了用户在设置界面看到的文案。主标题描述”配置了什么”,副标题描述”配置成了什么”。因为是动态生成的,你可以在用户配置了不同参数组合时显示不同的描述文案。这个细节直接影响用户对你的 Focus Filter 的理解程度。
参数类型的灵活性值得关注。除了标准的 Bool、String、Float 类型,你还可以用自定义 Entity 作为参数。这意味着”选择一个特定账号”、“选择一个特定日历”这种复杂参数也能被 Focus Filter 支持。
代码片段
定义一个 Focus Filter:
import AppIntents
// 定义你的 Focus 过滤器
struct MyFocusFilter: SetFocusFilterIntent {
static var title: LocalizedStringResource = "我的应用过滤器"
static var description = IntentDescription("根据专注模式调整应用行为")
// 必填参数:是否使用深色模式
@Parameter(title: "始终使用深色模式", default: false)
var alwaysUseDarkMode: Bool
// 可选参数:状态消息
@Parameter(title: "状态消息")
var statusMessage: String?
// 可选参数:自定义实体(账号)
@Parameter(title: "选择账号")
var account: AccountEntity?
// 动态显示配置摘要
static var displayRepresentation: DisplayRepresentation {
// 根据实际配置的参数动态生成显示文案
}
}
在应用中响应 Focus 变化:
// 当 Focus 切换时,系统调用 perform 方法
func perform() async throws -> some IntentResult {
// 读取当前 Focus 的配置值
if alwaysUseDarkMode {
// 切换到深色模式
ThemeManager.shared.applyDarkMode()
}
if let account = account {
// 切换到指定账号
AccountManager.shared.switchTo(account)
}
if let status = statusMessage {
// 更新状态消息
StatusManager.shared.update(status)
}
return .result()
}
最佳实践
- 必填参数给默认值:所有非 optional 的 Parameter 必须有合理默认值
- Display Representation 要写清楚:用户在 Focus 设置中看到的就是这些文案,模糊的描述会导致配置错误
- Focus 变化可能频繁发生:perform() 方法要做轻量处理,不要在这里做耗时操作
- 支持 App Extension:如果你的应用有后台需求,记得实现对应的 Extension 来接收 Focus 变更
- 减少干扰而非完全屏蔽:Focus Filter 的目的是帮用户聚焦,不是把功能全部锁死。考虑降低 badge 数量、收起不相关内容而不是完全隐藏
还有什么值得关注
- Focus Filter 的配置 UI 是系统自动生成的,你不需要自己画界面
- 与 App Intents 框架深度绑定,建议同步了解 App Intents 的 Entity 系统
- 多账号类应用是 Focus Filter 最自然的适配场景,如果你的应用支持”工作账号/个人账号”切换,这个功能几乎是必做的
- 系统在应用安装时就会读取 title 和 description,这两者是静态的,不支持动态更新
WWDC 2022