You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Apple Screen Time API使用求助:监控回调突然中断问题

Apple Screen Time API 示例代码与回调停止问题排查

一、基础Screen Time API(结合Family Controls)示例代码

1. 获取家长控制授权

import FamilyControls

let authorizationCenter = AuthorizationCenter.shared

authorizationCenter.requestAuthorization { status in
    guard status == .authorized else {
        // 处理未授权逻辑,比如提示用户开启权限
        return
    }
    // 授权成功后初始化监控
    setupDeviceActivityMonitoring()
}

2. 初始化设备活动监控

import DeviceActivity

func setupDeviceActivityMonitoring() {
    let deviceActivityCenter = DeviceActivityCenter.shared
    
    // 定义监控事件:比如每30分钟触发一次阈值提醒
    let usageEvent = DeviceActivityEvent(threshold: .init(minute: 30))
    let events: [DeviceActivityEvent.Name: DeviceActivityEvent] = [
        .init(rawValue: "30MinuteUsageAlert"): usageEvent
    ]
    
    // 设置监控时间段:比如从当前时间开始,持续1小时,每日重复
    let calendar = Calendar.current
    let intervalStart = calendar.dateComponents([.hour, .minute], from: Date())!
    let intervalEnd = calendar.dateComponents([.hour, .minute], from: Date(timeIntervalSinceNow: 3600))!
    
    let schedule = DeviceActivitySchedule(
        intervalStart: intervalStart,
        intervalEnd: intervalEnd,
        repeats: true,
        calendar: calendar,
        timezone: .current
    )
    
    let activityName = DeviceActivityName(rawValue: "DailyUsageMonitor")
    
    do {
        try deviceActivityCenter.startMonitoring(activityName, during: schedule, events: events)
    } catch {
        NSLog("启动监控失败:\(error.localizedDescription)")
    }
}

3. DeviceActivityMonitor扩展实现

import DeviceActivity
import FamilyControls

class DeviceActivityMonitor: DeviceActivityMonitorExtension {
    override func intervalDidStart(for activity: DeviceActivityName) {
        NSLog("监控时间段启动:\(activity.rawValue)")
    }
    
    override func intervalDidEnd(for activity: DeviceActivityName) {
        NSLog("监控时间段结束:\(activity.rawValue)")
    }
    
    override func eventDidReachThreshold(_ event: DeviceActivityEvent.Name, activity: DeviceActivityName) {
        NSLog("阈值触发:\(event.rawValue),对应活动:\(activity.rawValue)")
        
        // 示例:触发阈值后屏蔽指定App
        let controlsCenter = FamilyControlsCenter.shared
        let targetApps = ApplicationToken.currentApplications.filter { $0.bundleID == "com.example.targetApp" }
        controlsCenter.setAuthorizationStatus(.denied, for: targetApps)
    }
}

二、你的代码问题分析与回调停止解决方案

1. 核心问题:创建过多事件

你循环创建了60个每分钟触发的事件,这会触发系统资源限制——Screen Time对同时监控的事件数量有隐性上限,过多事件会导致系统丢弃回调甚至终止监控。

优化方案:

  • 只监控关键时间阈值(如10、30、60分钟),而非每分钟都创建事件;
  • 如果需要连续监控,可在事件触发后动态注册下一个时间段的监控,而非一次性批量注册。

优化后的代码示例:

var scheduleDuration = 60
// 只保留关键监控节点
let keyThresholds = [10, 30, 60]
var usageEvents: [DeviceActivityEvent.Name: DeviceActivityEvent] = [:]

for threshold in keyThresholds {
    guard threshold <= scheduleDuration else { continue }
    let event = DeviceActivityEvent(threshold: .init(minute: threshold))
    usageEvents[.init(rawValue: "scheduleID_\(threshold)")] = event
}

// 后续启动监控逻辑不变
let schedule = DeviceActivitySchedule(intervalStart: intervalStart, intervalEnd: intervalEnd, repeats: false)
let activityName = DeviceActivityName(rawValue: "\(scheduleID)")

do {
    try deviceActivityCenter.startMonitoring(activityName, during: schedule, events: usageEvents)
} catch {
    NSLog("Error monitoring device schedule - \(error.localizedDescription)")
}

2. 回调突然停止的其他排查点

  • 扩展生命周期:DeviceActivityMonitor是后台扩展,系统可能因资源紧张终止它。确保扩展Info.plist配置正确:
    • NSExtension -> NSExtensionPointIdentifier必须设为com.apple.deviceactivity-monitor;
    • 扩展内逻辑要轻量化,避免耗时操作。
  • Schedule有效性:检查intervalStart和intervalEnd的时间逻辑,若起始时间晚于结束时间、或时间已过期,监控会自动停止。建议每次启动前验证时间范围。
  • 权限状态:系统偶尔会丢失授权,可在主App定期检查AuthorizationCenter.shared.authorizationStatus,若变为未授权则重新请求。
  • 命名冲突:确保DeviceActivityEvent.Name和DeviceActivityName的rawValue唯一,重复命名会覆盖旧监控导致回调异常。
  • 系统节流:iOS对Screen Time监控频率有控制,过于频繁的事件触发会被系统节流,建议合理设置阈值间隔。

内容的提问来源于stack exchange,提问作者Akilan C B

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 19:01:18