System & Services 进阶 20m
Screen Time API 的新功能
What's new in Screen Time API
2022年6月6日
一句话判断
Screen Time API 不再只是家长控制工具——个人用户授权和自定义使用报告让它的应用场景大幅扩展。
这场 Session 讲了什么
iOS 15 引入的 Screen Time API 包含三个框架:Family Controls(授权入口)、Managed Settings(限制和屏蔽)、Device Activity(时间窗口和阈值响应)。但这些框架最初只支持家长对儿童设备的管控场景。
iOS 16 带来了三项重大更新。第一,Family Controls 新增个人用户授权模式——用户可以对自己的设备授权,不再限于家长管控。这意味着 Screen Time API 可以用于个人效率工具,不仅仅是家长控制 App。第二,Managed Settings Store 支持命名存储——每个进程最多创建 50 个命名 Store,且自动在 App 和 Extension 之间共享。第三,Device Activity 新增了自定义报告功能,通过 SwiftUI 构建完全自定义的使用报告 UI。
Session 用一个名为 Worklog 的示例 App 贯穿始终,展示了如何利用这些新 API 构建一个帮助职场新人养成良好习惯的工具。
值得深挖的点
- 个人授权 vs 家长授权:个人授权模式下,用户对自己设备授权。与家长授权的关键区别是:不限制 iCloud 登出、不限制 App 删除、同一设备可以有多个 App 同时使用个人授权。这为效率类 App 打开了大门。
- 命名 Managed Settings Store:这是最实用的新功能。你可以为不同类别创建不同的 Store(比如”游戏”Store 屏蔽游戏网站,“社交”Store 屏蔽社交媒体),系统自动应用最严格的设置。清除某个 Store 的设置不会影响其他 Store。
- Device Activity Report:新的报告扩展点让你用 SwiftUI 构建自定义的使用报告。框架提供原始使用数据,你负责展示逻辑。报告内容通过
DeviceActivityReport.Context关联到特定的时间窗口和过滤条件。 - async/await 全面采用:授权请求现在完全基于 async/await,代码更简洁,错误处理更直观。
代码片段
// 个人用户授权请求
let center = AuthorizationCenter.shared
do {
try await center.requestAuthorization(for: .individual)
// 用户通过 Face ID/Touch ID 验证后授权成功
} catch {
// 处理授权失败
}
// 创建命名 Managed Settings Store
let gamingStore = ManagedSettingsStore(named: "Gaming")
gamingStore.shield.webContent = .all // 屏蔽所有游戏网站
let socialStore = ManagedSettingsStore(named: "Social")
socialStore.shield.applicationCategories = .all // 屏蔽社交媒体
// 清除特定 Store 的设置(不影响其他 Store)
socialStore.clearAllSettings()
// 自定义 Device Activity Report
struct PieChartReport: DeviceActivityReport {
let context: DeviceActivityReport.Context = .pieChart
let filter: DeviceActivityFilter = {
// 定义报告的时间范围和数据来源
DeviceActivityFilter(
segment: .daily(
during: Calendar.current.dateInterval(
of: .day, for: Date()
)!
)
)
}()
func makeConfiguration(
representing data: DeviceActivityResults<ActivityCategory>
) -> PieChartView.Configuration {
// 将使用数据映射到饼图配置
var segments: [PieSegment] = []
for await category in data {
for await activity in category.activity {
segments.append(
PieSegment(
name: activity.displayValue,
duration: activity.duration
)
)
}
}
return PieChartView.Configuration(segments: segments)
}
}
最佳实践
- 优先使用个人授权模式构建效率类工具,市场远大于家长控制
- 为不同功能创建独立的命名 Store,利用”最严格设置优先”的特性组合管理
- Device Activity Report 尽量在 Extension 中处理数据聚合,只把结果传给主 App
- 授权状态变化时及时更新 UI,利用
AuthorizationCenter.$authorizationStatus监听变化 - 使用报告功能时注意隐私——用户数据只在他们自己的设备上处理
还有什么值得关注
- Family Controls 的 opaque token 机制保证用户隐私,你的 App 无法知道具体屏蔽了哪些 App
- Device Activity Extension 的运行时间和内存有限,报告逻辑要精简
- 搭配 Focus Filters 可以构建更精细的场景化限制方案
- App 的授权可以在”设置 > 屏幕使用时间”中被用户随时撤销
WWDC 2022