如何在iOS应用中使用Screen Time API获取用户总屏幕使用时间
基于DeviceActivity框架实现iOS屏幕使用时间统计
我仅上过iOS编程入门课,曾用模拟数据制作过示例应用,目前完全不清楚DeviceActivity框架的实际操作方法,需要解决以下两个问题:
- 为此类Device API请求授权
- 获取并展示用户的总屏幕使用时间
以下是修改后的完整实现代码,包含授权处理和屏幕时间获取的核心逻辑:
1. 应用入口(Worklog App)
负责初始化授权请求,确保用户授予访问屏幕时间数据的权限:
import SwiftUI import DeviceActivity import FamilyControls @main struct Worklog: App { let authCenter = AuthorizationCenter.shared var body: some Scene { WindowGroup { ContentView() .onAppear { Task { do { // 请求DeviceActivity相关授权 try await authCenter.requestAuthorization(for: .deviceActivity) } catch { print("授权失败:\(error.localizedDescription)") } } } } } }
注意:必须在
Info.plist中添加NSFamilyControlsUsageDescription键,填写向用户说明获取屏幕时间数据的用途(比如"需要访问您的屏幕时间数据以生成使用报告"),否则授权请求会直接失败。
2. 主界面与屏幕时间获取逻辑(ContentView)
包含导航界面和屏幕时间查询的核心代码:
import SwiftUI import DeviceActivity struct ContentView: View { var body: some View { NavigationView { VStack { Text("Welcome to the first view") } .toolbar { NavigationLink(destination: APICall()) { Text("Next") } } .navigationBarTitle("First View") } } } struct APICall: View { @State private var screenTime: Double? = nil @State private var error: Error? = nil // 初始化DeviceActivity中心,用于查询使用数据 private let activityCenter = DeviceActivityCenter.shared var body: some View { VStack { HStack { Image(systemName: "clock") .resizable() .frame(width: 50, height: 50) .aspectRatio(contentMode: .fit) .padding(.leading, 20) VStack(alignment: .leading) { if let screenTime = screenTime { Text("Total screen time: \(String(format: "%.2f", screenTime)) hours") .font(.title) .foregroundColor(.primary) } else { Text("Press the button to fetch screen time") .font(.title) .foregroundColor(.secondary) } } Spacer() } .padding(.vertical, 20) Button(action: fetchScreenTime) { Text("Fetch screen time") .font(.title) .foregroundColor(.white) .padding() .background(LinearGradient(gradient: Gradient(colors: [.red, .orange]), startPoint: .topLeading, endPoint: .bottomTrailing)) .cornerRadius(10) .overlay( RoundedRectangle(cornerRadius: 10) .stroke(Color.white, lineWidth: 4) ) } if let error = error { Text("Error: \(error.localizedDescription)") .foregroundColor(.red) .padding(.top) } } .padding() } func fetchScreenTime() { Task { do { // 定义查询时间段:过去24小时 let endDate = Date() let startDate = endDate.addingTimeInterval(-24 * 60 * 60) let interval = DateInterval(start: startDate, end: endDate) // 查询该时间段内的所有应用使用数据 let activityReports = try await activityCenter.activityReports(for: interval) // 计算总屏幕使用时长(转换为小时) let totalSeconds = activityReports.reduce(0) { total, report in total + report.activitySegments.reduce(0) { segmentTotal, segment in segmentTotal + segment.duration } } screenTime = totalSeconds / 3600 error = nil } catch { self.error = error screenTime = nil } } } }
关键说明:
- 授权请求必须在应用启动时触发,且必须配置
Info.plist权限描述 DeviceActivityCenter用于查询指定时间区间内的屏幕使用数据,每个activityReport对应一个应用,包含多个使用时段的时长- 总时长计算需要累加所有应用的所有使用时段的秒数,再转换为小时格式
内容的提问来源于stack exchange,提问作者Luke Bender
相关产品推荐
相关产品推荐

