Swift屏幕时间应用:Firebase同步数据至问责伙伴的可行性与实现
方案可行性与实现指南
一、方案可行性
完全可行。Apple的屏幕时间权限允许获取总屏幕使用时长(无需应用细分数据),只要用户授予对应权限即可,不会触发额外隐私限制——你仅请求汇总时长,未涉及应用级细分数据,符合Apple隐私规范。
二、具体实现步骤
1. 申请屏幕时间权限
- 在
Info.plist中添加NSScreenTimeUsageDescription键,填写明确的权限用途(例如"为让你的问责伙伴查看总屏幕使用时长")。 - 使用
ScreenTime框架发起授权请求:import ScreenTime STAuthorizationCenter.shared.requestAuthorization { status in switch status { case .authorized: // 授权成功,可获取屏幕时间数据 case .denied, .restricted: // 处理授权失败逻辑,提示用户开启权限 @unknown default: break } }
2. 获取总屏幕时间
通过STActivitySummary查询指定时间段的总活跃时长(以当天为例):
func getTotalScreenTime() -> TimeInterval? { guard STAuthorizationCenter.shared.authorizationStatus == .authorized else { return nil } let calendar = Calendar.current let startOfDay = calendar.startOfDay(for: Date()) let endOfDay = calendar.date(byAdding: .day, value: 1, to: startOfDay)! do { let summaries = try STActivitySummary.queryActivitySummaries(startDate: startOfDay, endDate: endOfDay) guard let summary = summaries.first else { return nil } // totalActiveTime 为总活跃时长(单位:秒) return summary.totalActiveTime } catch { print("获取屏幕时间失败: \(error.localizedDescription)") return nil } }
3. 向下取整到最近0.5小时并控制更新逻辑
实现取整函数,仅当取整后数值变化时触发后续更新:
// 存储上次上报的取整值,避免重复同步 private var lastReportedValue: Double? func formatAndCheckUpdate(_ totalSeconds: TimeInterval) -> String? { let totalHours = totalSeconds / 3600 // 向下取整到最近0.5小时:1.716小时→1.5,2.166小时→2.0 let roundedHours = floor(totalHours * 2) / 2 // 仅当数值变化时返回格式化结果,否则返回nil跳过更新 guard roundedHours != lastReportedValue else { return nil } lastReportedValue = roundedHours return "\(roundedHours)小时+" }
4. 同步数据到Firebase实时数据库
- 确保用户已通过Firebase Auth完成登录,获取唯一用户ID。
- 当取整后数值变化时,将数据写入指定节点:
import FirebaseDatabase func syncToFirebase(formattedTime: String) { guard let userId = Auth.auth().currentUser?.uid else { return } let targetRef = Database.database().reference().child("users").child(userId).child("accountability") targetRef.setValue(["totalScreenTime": formattedTime]) { error, _ in if let error = error { print("同步数据失败: \(error.localizedDescription)") } } }
5. 问责伙伴获取数据
- 用户需主动将自己的
userId共享给问责伙伴(可通过邀请码、通讯录匹配等方式)。 - 伙伴通过对方
userId读取对应数据:
func fetchPartnerScreenTime(partnerUserId: String, completion: @escaping (String?) -> Void) { let targetRef = Database.database().reference().child("users").child(partnerUserId).child("accountability") targetRef.observeSingleEvent(of: .value) { snapshot in guard let dataDict = snapshot.value as? [String: String], let screenTime = dataDict["totalScreenTime"] else { completion(nil) return } completion(screenTime) } }
三、注意事项
- 隐私合规:必须明确告知用户数据仅共享给其指定的问责伙伴,且仅包含总屏幕时长,无应用细分信息。
- 权限失效处理:若用户后续撤销屏幕时间权限,需提示用户重新授权,并暂停数据同步。
- Firebase权限配置:需设置数据库规则,确保只有用户本人及授权伙伴能读取对应数据(例如在用户节点下存储伙伴ID列表,规则中校验访问者身份)。
内容的提问来源于stack exchange,提问作者Aishah Hamman
相关产品推荐
相关产品推荐

