WWDC Quick Look 💓 By SwiftGGTeam
What's new in Screen Time API

What's new in Screen Time API

观看原视频

Highlight

iOS 16 扩展了 Screen Time API 的使用范围:个人用户现在可以授权第三方 App 管理自己的设备使用习惯,Managed Settings Store 支持命名存储并在 App 与 Extension 间自动共享,Device Activity 新增了基于 SwiftUI 的自定义报告能力。

核心内容

从家长控制到个人效率

iOS 15 的 Screen Time API 只能用于家长控制场景——家长通过 iCloud 认证管理孩子的设备。这个定位限制了应用场景,很多想帮用户管理自己屏幕时间的开发者被挡在门外。

iOS 16 新增了个人用户授权模式(AuthorizationCenter.requestAuthorization(for: .individual))。用户在自己的设备上直接授权,不需要家庭共享关系。每个设备可以授权多个 App,应用卸载和 iCloud 登出的强制限制也取消了。

这意味着 Screen Time API 的市场从”家长控制”扩展到了”个人效率”——专注工具、习惯养成、数字健康等方向都能使用。

命名存储解决多场景冲突

04:20

iOS 15 的 Managed Settings Store 每个进程只有一个,App 和 Extension 还不能共享。想实现”工作日屏蔽社交 App、周末开放”这种需求,代码写起来很别扭。

iOS 16 支持每个进程创建最多 50 个命名 Store,且自动在 App 和所有 Extension 之间共享:

let gamingStore = ManagedSettingsStore(named: .gaming)
let socialStore = ManagedSettingsStore(named: .social)

不同 Store 的设置如果冲突,最严格的那个生效。比如 Gaming Store 屏蔽了某个游戏网站,即使 Social Store 清除了所有限制,该网站仍然保持屏蔽。

自定义使用报告

06:35

iOS 16 新增了 Device Activity Report Extension,开发者可以用 SwiftUI 构建完全自定义的设备使用报告。数据在设备本地处理,不涉及云端传输,保护用户隐私。

详细内容

请求个人授权

03:09

App 启动时请求授权:

import SwiftUI
import FamilyControls

@main
struct Worklog: App {
    let center = AuthorizationCenter.shared
    var body: some Scene {
        WindowGroup {
            VStack {}
                .onAppear {
                    Task {
                        do {
                            try await center.requestAuthorization(for: .individual)
                        } catch {
                            print("Failed to enroll with error: \(error)")
                        }
                    }
                }
        }
    }
}

关键点:

  • AuthorizationCenter.shared 是单例,整个 App 使用同一个实例
  • .individual 参数指定个人授权模式,区别于 .child 的家长控制模式
  • 使用 async/await 处理异步授权流程
  • 首次调用会弹出系统 alert,用户点击 Allow 后需要 Face ID / Touch ID / 密码验证
  • 授权成功后再次调用会静默成功,不会重复弹窗

授权完成后,设置中会新增两个开关:

  • 设置 > 屏幕使用时间 > 拥有屏幕使用时间访问权限的 App
  • 设置 > [App 名称] > 屏幕使用时间限制

用户可以随时在这两个位置取消授权。

使用命名 Store 管理不同场景

05:13

在 Device Activity Monitor Extension 中响应时间窗口:

import DeviceActivity
import ManagedSettings

class WorklogMonitor: DeviceActivityMonitor {
    let database = BarkDatabase()
    
    override func intervalDidStart(for activity: DeviceActivityName) {
        super.intervalDidStart(for: activity)
        let socialStore = ManagedSettingsStore(named: .social)
        socialStore.clearAllSettings()
    }
    
    override func intervalDidEnd(for activity: DeviceActivityName) {
        super.intervalDidEnd(for: activity)
        let socialStore = ManagedSettingsStore(named: .social)
        let socialCategory = database.socialCategoryToken
        socialStore.shield.applicationCategories = .specific([socialCategory])
        socialStore.shield.webDomainCategories = .specific([socialCategory])
    }
}

关键点:

  • ManagedSettingsStore(named: .social) 创建/访问名为 social 的 Store
  • clearAllSettings() 一键清除该 Store 的所有限制
  • shield.applicationCategories 屏蔽特定应用类别
  • shield.webDomainCategories 屏蔽特定网站类别
  • intervalDidStart 在时间窗口开始时调用(如晚上 5 点开放社交 App)
  • intervalDidEnd 在时间窗口结束时调用(如晚上 8 点重新屏蔽)

创建自定义使用报告

07:02

主 App 中定义报告上下文和过滤器:

import SwiftUI
import DeviceActivity

extension DeviceActivityReport.Context {
    static let pieChart = Self("Pie Chart")
}

@main
struct Worklog: App {
    private let thisWeek = DateInterval(...)
    @State private var context: DeviceActivityReport.Context = .pieChart
    @State private var filter = DeviceActivityFilter(
        segment: .daily(during: thisWeek)
    )

    var body: some Scene {
        WindowGroup {
            GeometryReader { geometry in
                VStack(alignment: .leading) {
                    DeviceActivityReport(context: context, filter: filter)
                        .frame(height: geometry.size.height * 0.75)
                }
            }
        }
    }
}

关键点:

  • DeviceActivityReport.Context 定义报告类型标识
  • DeviceActivityFilter 指定数据时间范围,支持 .daily.weekly 等分段方式
  • DeviceActivityReport 是 SwiftUI 视图,直接嵌入界面

在 Report Extension 中处理数据:

import SwiftUI
import DeviceActivity

struct PieChartReport: DeviceActivityReportScene {
    let context: DeviceActivityReport.Context = .pieChart
    let content: (PieChartView.Configuration) -> PieChartView
    
    func makeConfiguration(representing data: [DeviceActivityData]) 
        -> PieChartView.Configuration {
        var totalUsageByCategory: [ActivityCategory: TimeInterval]
        totalUsageByCategory = data.map()
        
        return PieChartView.Configuration(
            totalUsageByCategory: totalUsageByCategory
        )
    }
}

关键点:

  • DeviceActivityReportScene 是 Report Extension 的协议
  • makeConfiguration 在数据更新时自动调用,不需要手动触发
  • 返回的 Configuration 作为视图模型传给 SwiftUI 视图

Extension 入口:

import SwiftUI
import DeviceActivity

@main
struct WorklogReportExtension: DeviceActivityReportExtension {
    var body: some DeviceActivityReportScene {
        PieChartReport { configuration in
            PieChartView(configuration: configuration)
        }
    }
}

核心启发

  • 做什么:构建个人专注助手,按时间段自动屏蔽干扰 App

  • 为什么值得做:iOS 16 的个人授权模式让这类工具不再需要家庭共享关系,目标用户从家长扩展到所有 iPhone 用户

  • 怎么开始:用 AuthorizationCenter.shared.requestAuthorization(for: .individual) 获取授权,创建 ManagedSettingsStore 配置屏蔽规则,用 DeviceActivitySchedule 定义时间窗口

  • 做什么:开发团队屏幕时间管理工具,帮助企业监控工作设备使用情况

  • 为什么值得做:Apple Business Essentials 配合 Screen Time API 可以实现企业级设备使用策略

  • 怎么开始:结合 Managed Apple ID 和 Device Activity Report 生成团队使用报告

  • 做什么:创建儿童数字习惯养成游戏,用成就系统替代强制限制

  • 为什么值得做:传统的家长控制容易引起对抗,游戏化方式更容易被接受

  • 怎么开始:用 Device Activity Report 展示使用数据,结合 Game Center 成就系统,达标后自动放宽限制

  • 做什么:构建网站/App 使用分析工具,帮用户了解自己的时间分配

  • 为什么值得做:自定义报告 Extension 可以用 SwiftUI 画出精美的数据可视化

  • 怎么开始:创建 DeviceActivityReportExtension,在 makeConfiguration 中聚合 DeviceActivityData,用 Swift Charts 或自定义视图渲染

关联 Session

评论

GitHub Issues · utterances