I am trying to understand how to approach 'x minute' pauses for a DeviceActivitySchedule.
For instance, I would like to let the user pause for 5 minutes from an active schedule (meaning un-shielding the apps and re-applying the shield after the 5 min has passed).
The only way that came to my mind was calling the following:
- Calling
.startMonitoring
to start monitoring a new event with the same apps starting.now
and ending.now + 5 minutes
; - Calling in the
intervalDidStart
,store.shield.applications.subtract(apps)
so that the apps are removed from the shield. - Calling in the
intervalDidEnd
,store.shield.applications = apps
so that the apps are now shielded again.
The problem is that, from the Apple Developer Documentation:
The minimum interval length for monitoring device activity is fifteen minutes.
So the minimum pause I could offer to the user would be 15 minutes.
And that tells me this approach is most likely wrong, because all other Screen Time apps, like Opal, Jomo, AppBlock offer also 5 min pause.
Does anyone know / can think of a different and better approach?
The answer actually lies in the recoverySuggestion
when you convert the DeviceActivity.DeviceActivityCenter.MonitoringError.intervalTooShort
error to LocalizedError
(I don't know why they hide it there 😂)
"The minimum interval length for monitoring device activity is fifteen minutes. Consider using the
warningTime
property of an activity’s schedule to receive callbacks that are more granular than fifteen minutes."
Doc of warningTime
: https://developer.apple.com/documentation/deviceactivity/deviceactivityschedule/warningtime
e.g. For a one-minute break, we can set the end time to be 15 minutes later and set the warningTime to be 14 minutes. Then intervalWillEndWarning will be called and we can treat it as the end time to end the break directly.
let now = Date.now
let start = Calendar.current.dateComponents([.hour, .minute, .second], from: now)
let fakeEnd = Calendar.current.dateComponents([.hour, .minute, .second], from: now.advanced(by: 15*60))
try deviceActivityCenter.startMonitoring(.breakTime, during: .init(intervalStart: start, intervalEnd: fakeEnd, repeats: false, warningTime: DateComponents(minute: 14)))