Same here. Because DeviceActivityMonitor is generally flakey, we emit an event when intervalDidStart isn't called (as determined by intervalDidStart flipping a bit that lives in a UserDefaults container shared with the main app)
Here is a graph of those events, broken down by iOS version on which they occurred.
It is an iOS 17 problem. Contrast that with all app events, broken down by iOS version and which they occurred. iOS 17.4 is way overrepresented in the first, iOS 16.x is way underrepresented.
Post
Replies
Boosts
Views
Activity
In this case I'm not even sure what filing a Feedback Assistant would look like - this since it's entirely a UI problem and one that unreliably occurs. But I assure any reader it's a real issue.@Kmart are you able to provide any update on this?
Same here. @kmart any guidance?
That's helpful thanks - we are seeing it in prod in pre-16.4 cases. I'm seeing cases of it popping back up in 16.6 as well so there may have been a regression
Seeing the same fwiw. Makes the logs incredibly difficult to read
kind of. I think the following works
do {
try await center.requestAuthorization(for: .individual)
} catch {
if let errorType = error as? FamilyControlsError {
switch (errorType) {
case .unavailable:
// If I'm understanding the documentation correctly, execution will reach this block if ScreenTime is disabled
}
}
source: https://developer.apple.com/documentation/familycontrols/familycontrolserror
Is there anyway to forcibly remove a website from the FamilyActivityPicker? Would deleting Safari browsing history do it, for example?
// stop monitoring existing activities
let activityName = "10minuteUse"
let relevantActivities = activities.filter({$0.rawValue.contains(activityName)})
if (!relevantActivities.isEmpty) {
deviceActivityCenter.stopMonitoring(relevantActivities)
}
// generate details of new activity
let intervalLengthInSeconds = 20 * 60
var sessionEvents = [DeviceActivityEvent.Name : DeviceActivityEvent]()
sessionEvents[DeviceActivityEvent.Name(eventType: .sessionEnd)] = DeviceActivityEvent(applications: [token],
threshold: DateComponents(minute: 10))
let intervalEnd = Date(timeIntervalSinceNow: TimeInterval(intervalLengthInSeconds))
// this is what appears to be causing the threshold to be insta-breached.
// using Date() here instead doesn't.
let intervalStart = Date(timeIntervalSinceNow: 60)
let schedule = DeviceActivitySchedule(intervalStart: Calendar.current.dateComponents([.hour, .minute], from: intervalStart),
intervalEnd: Calendar.current.dateComponents([.day, .hour, .minute], from: intervalEnd),
repeats: false,
warningTime: DateComponents(minute: 1))
let newActivity = DeviceActivityName(rawValue: activityName)
// create new activity
do {
try deviceActivityCenter.startMonitoring(newActivity, during: schedule, events: sessionEvents)
} catch {
print("failed to start session: \(error.localizedDescription)")
}
Correct I'm using .webContent.blockedByFilter for the latter scenario I described (explicitly providing a URL).
I'm using .shield.webDomains for the former. Thanks for the clarification. I feel it's confusing that as developers we have the ability to shield arbitrary domains but not display a relevant message on that shield or modify the behavior of it. It can be unclear to users which app is even generating the shield. I'll file a report. Two follow-up questions:
Can you confirm that the only way to get a WebDomainToken is from a FamilyActivitySelection generated by the user? The reason this is relevant is for non-safari iOS users - the web domains they use frequently in their non-safari browser do not appear in the FamilyActivityPicker.
Is there documentation on how the FamilyActivityPicker selects which WebDomains are present? How far back in user history is used, etc.