Screen Time

RSS for tag

Share and manage web-usage data, and observe changes made to Screen Time settings by a parent or guardian.

Screen Time Documentation

Posts under Screen Time tag

149 Posts
Sort by:
Post not yet marked as solved
0 Replies
208 Views
I have two repeating DeviceActivitySchedules running in my app and noticed a super strange behavior: whenever I modify Screen Time API permission settings (granting an additional app permission, or removing permission for a different app (completely different unrelated screen time apps from App Store)) all my DeviceActivitySchedules are cancelled and the intervalDidEnd callbacks are called my permission is not modified in this scenario this is a super strange and unexpected behavior is anyone able to reproduce this? for me this happens 100% of the times I do this any known workarounds?
Posted
by
Post not yet marked as solved
0 Replies
243 Views
Hello, I am using a DeviceActivityEvent to limit access to an app after the user has spent x minutes on it. Sometimes it can happen that a DeviceActivitySchedule spans from 11:55pm - 12:25am (just an example). In these cases, I have noticed, the DeviceActivityMonitorExtension’s eventDidReachThreshold is not called after the user has reached the threshold time interval in the observed app. I assume this is because we have transitioned over midnight and something weird happens to the DeviceActivitySchedule. I’ve tried adding the day components to the DeviceActivitySchedule as well, but then it fails completely. Any advice how to handle this? I could, of course, create two separate DeviceActivitySchedules: one for before midnight, and one for after. But depending on the user’s real app usage that could lead to slightly different (and unexpected) behavior.
Posted
by
Post not yet marked as solved
0 Replies
242 Views
If we want to un-shield category/application for particular schedule, then what is the mechanism for this, as for now we are using ManagedSettingsStore().shield.applications = nil and ManagedSettingsStore().shield.applicationCategories = nil, which is actually un-shielding all category/applications without considering the selection of category/application for that schedule. What is the best approach to handle multiple schedules for shielding of apps?
Posted
by
Post not yet marked as solved
2 Replies
750 Views
Update 1: Seems like app limits do work, but they don't account for time spent already in the day (only counts it since it first was scheduled? - but just guessing). This seems to be the change in behavior that is making it seem like broken. I have an app that uses individual FamilyControls / Screen Time authorization. I am still investigating but reporting ASAP. Will add feedback and more later. I am not sure what's going on, but so far: App limits generally work fine throughout the day(?) At around 9 PM they stop working if I clear ManagedSettingStore/DeviceActivityCenter (it might be unrelated to the time, but just clearing, but this is just what I know so far) I tried setting app limits from Apple's Setting app (so I could see if it's not just my app, and that system could have issues) and it crashes. The whole Settings app freezes and then crashes. (edit: after some freezing, including in the app picker, I was able to set a limit and it worked...did notice some odd behavior where 1 minute break did not work, but selecting 15 minute break did work) going to also update: FB13688616
Posted
by
Post not yet marked as solved
0 Replies
191 Views
It's no secret, the Screen Time/Family Controls API is incredibly challenging to figure out. If you want to talk with other people building on the API, join the discord here: https://discord.gg/sjxhKWgry4 I want to connect with other people building so I made a discord where we can discuss challenges, updates & questions in more depth.
Posted
by
Post not yet marked as solved
1 Replies
258 Views
I'm using the Screen Time API to shield apps the user selects. The problem is, that the apps are always shielded, even outside of the schedule. Here is my function initiateMonitoring: func initiateMonitoring(scheduleStart: DateComponents, scheduleEnd: DateComponents) { let schedule = DeviceActivitySchedule( intervalStart: scheduleStart, intervalEnd: scheduleEnd, repeats: true ) let center = DeviceActivityCenter() do { try center.startMonitoring(.daily, during: schedule) logger.log("STARTED MONITORING") } catch { logger.log("FAILED MONITORING: \(error.localizedDescription)") } } The expected result should be that the selected Apps should be blocked during the schedule the user specified, but not outside the schedule, but it is blocked 24/7. I've experimented with the DateComponents, but the issue may be somewhere else. What's maybe interesting is, I tried Logging the DeviceActivityMonitor and somehow it doesn't get called. The logging-output from initiateMonitoring is printed in the console, but for the DeviceActivityMonitor it's not. I implemented it as recommended as a separate Extension Target. For more context, here is my DeviceActivityMonitor: class DeviceActivityMonitorExtension: DeviceActivityMonitor { let store = ManagedSettingsStore() let logger = Logger() override func intervalDidStart(for activity: DeviceActivityName) { super.intervalDidStart(for: activity) logger.log("INTERVAL STARTED") let model = ShieldManager.shared let applications = model.selectionToDiscourage.applicationTokens let categories = model.selectionToDiscourage.categoryTokens let webCategories = model.selectionToDiscourage.webDomainTokens store.shield.applications = applications.isEmpty ? nil : applications store.shield.applicationCategories = ShieldSettings.ActivityCategoryPolicy.specific(categories, except: Set()) store.shield.webDomains = webCategories.isEmpty ? nil : webCategories } ... What's confusing me is that the apps are in fact shielded, so the MonitorExtension should be called, but neither the logging works nor my separate ShieldConfigurationExtension, maybe the issues are connected... Any help would be gladly appreciated!
Posted
by
Post not yet marked as solved
0 Replies
228 Views
I am currently developing an app to help people focus on their work. I use familycontrols , managedsettings and devie activity to develop it. I am currently facing an issue where I would like to hide the app selected by the user from the main screen and resource library. But I did not find any relevant information in the document. Who can help me.
Posted
by
Post not yet marked as solved
0 Replies
271 Views
There is a way to allow DeviceActivityMonitor to make UI changes? Currently I have some code in the intervalDidStart and intervalDidEnd that updates Core Data entities, and it works correctly. However, the changes are only reflected if the app is terminated and opened again. Thus, if the app is opened and one of the methods inside the DeviceActivityMonitor is being called, the UI won't be updated. PS: I am using @FetchRequest to retrieve the core data entities called BlockEntity, and I have a little circle in the UI which should indicate the status of the block: active/inactive, so it would be nice to update the color in real time when intervalDidStart or intervalDidEnd are called.
Posted
by
Post marked as solved
1 Replies
409 Views
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?
Posted
by
Post not yet marked as solved
1 Replies
274 Views
An app that uses screen time API. After asking for permission and receiving them works, everything generally work, shields applications etc.. Upon new version update (manually update from testFlight old version or App Store) I get an error message, I can then update again without any error but the permissions are revoked and I have to ask for them again. shielding stopes. This happens randomly on TestFlight or App Store and the permissions Did anyone encounter this or solved this? this seems to have started a month ago but maybe I just missed it before
Posted
by
Post not yet marked as solved
0 Replies
157 Views
Anyone had any luck modifying any of the Activity pickers with the view modifer. We've tried preferredColorScheme(_:) with no luck. Stuck with black icons half the time - which doesn't match our UI. We've had even less luck modifying the activityPicker sheet view to match our UI. A gigantic 'Choose Activity' sits right in the middle of our activity selection page which already has our own specific headers. Not to mention trying add accessibility option into these views. Anyone had better luck modifiying the activity picker views?
Posted
by
Post not yet marked as solved
0 Replies
192 Views
Hello, I want to make a simple project that simply displays the user's current daily ScreenTime. I believe you may be able to do the functionality I want with: FamilyControls or ScreenTime. I believe that you may need to pay for the paid developer account in order to access the FamilyControl framework. I am having trouble finding guidance as to how I would do this as most reddit/stackoverflow posts are incomplete with answers and I cannot find demos/code examples/tutorials/sample usage anywhere on google. I would greatly appreciate any help and guidance. If the solution requires the paid developer tier, I am fine with that. Thank you in advance
Posted
by
Post not yet marked as solved
0 Replies
174 Views
So I woke up today and I saw a screen time limit was placed on my phone. No one in my family placed the screentime limit, and I never placed one when I got my phone. I dont know a screen time passcode because I never made one, because I never set up a screentime limit. I tried restarting and force restarting, didnt work, I have no new updates so that doesnt work either. I dont know what to do. Ive watched like 6 hour video essays on this phone, and its never gave me a screentime limit or warning, so I know its a bug.
Posted
by
Post not yet marked as solved
0 Replies
240 Views
I have implemented a shielding mechanism via Family Controls to prevent unauthenticated users from deleting specific shortcuts within the Shortcuts app. While this successfully secures the app, it has an unintended consequence: the Shortcuts app no longer appears in Spotlight Search and becomes inaccessible for users subject to this shielding. I understand that this is the default behavior when implementing app shielding or time limits on specific apps. Is there a way to retain the app's visibility in Spotlight Search despite it being shielded?
Posted
by
Post marked as solved
2 Replies
309 Views
I'm developing an iOS app that uses ScreenTime API. Locally, everything works as expected - I have two physical devices in one Apple Family, and calling AuthorizationCenter.shared.requestAuthorization(for: .child) on a child device shows standard authorization dialog. Currently the app is in a review by Apple, and they are saying they can't authorize as a child. From logs, and a screenshots provided by them, I see that on AuthorizationCenter.shared.requestAuthorization(for: .child) call, FamilyControlsError.restricted error is being thrown. I didn't encounter this error once during development and can't simulate this issue now either. Tried everything - authorization on account that is not a child, not in a family, tried restricting everything possible for a child's device from ScreenTime settings. This specific error is never triggered. Does anyone have idea why this error could happen? My last guess is the review team is using an enterprise account and that somehow intercepts with ScreenTime settings. But I don't have an enterprise account to test this theory.
Posted
by
Post not yet marked as solved
1 Replies
450 Views
Is there a way for me to programmatically check whether a user has disabled my app's access to Screen Time? I currently request Family Controls / Screen Time access upon download by calling the following: AuthorizationCenter.shared.requestAuthorization(for: .individual) I need to be able to detect, though, when a user has gone into Settings -> Screen Time and disabled my app's Screen Time access. I tried calling the following: AuthorizationCenter.shared.authorizationStatus But it appears to have a value of Approved even after I turn off my app's Screen Time access. Is there any way to accurately detect this in the code?
Posted
by
Post not yet marked as solved
2 Replies
483 Views
I am developing a project with the Screen Time API, and I cannot understand why the methods inside DeviceActivityMonitor extension are not being called. Some points to note: I do start by requesting authorization from the User (this is working as expected when opening the app) Both the DeviceActivityMonitor Extension and the main app are under the same App Group I have added Family Controls capability to both targets and have the developer account to use it. I start by calling center.startMonitoring() I have overridden the original methods. Yet, when startMonitoring is called, there is no action that is supposed to be taken that is being taken, and as far as I can tell, the methods aren't even being called. Here are some relevant snippets of code: // EXT class DeviceActivityMonitorExtension: DeviceActivityMonitor { override func intervalDidStart(for activity: DeviceActivityName) { super.intervalDidStart(for: activity) let store = ManagedSettingsStore(named: .daily) } override func intervalDidEnd(for activity: DeviceActivityName) { super.intervalDidEnd(for: activity) let store = ManagedSettingsStore(named: .daily) store.clearAllSettings() } override func eventDidReachThreshold(_ event: DeviceActivityEvent.Name, activity: DeviceActivityName) { super.eventDidReachThreshold(event, activity: activity) let store = ManagedSettingsStore(named: .daily) let model = BeeFreeModel.shared let applications = model.selectionToDiscourage.applicationTokens let categories = model.selectionToDiscourage.categoryTokens let webDomains = model.selectionToDiscourage.webDomainTokens store.shield.applications = applications.isEmpty ? nil : applications store.shield.applicationCategories = categories.isEmpty ? nil : ShieldSettings.ActivityCategoryPolicy.specific(categories) store.shield.webDomains = webDomains.isEmpty ? nil : webDomains } } // APP extension DeviceActivityName { static let daily = Self("daily") } extension DeviceActivityEvent.Name { static let discouraged = Self("discouraged") } let schedule = DeviceActivitySchedule( intervalStart: DateComponents(hour: 0, minute: 0, second: 0), intervalEnd: DateComponents(hour: 23, minute: 59, second: 59), repeats: true ) class BeeFreeSchedule { static public func setSchedule() { print("Setting schedule...") print("Hour is: ", Calendar.current.dateComponents([.hour, .minute], from: Date()).hour!) let events: [DeviceActivityEvent.Name: DeviceActivityEvent] = [ .discouraged: DeviceActivityEvent( applications: BeeFreeModel.shared.selectionToDiscourage.applicationTokens, categories: BeeFreeModel.shared.selectionToDiscourage.categoryTokens, webDomains: BeeFreeModel.shared.selectionToDiscourage.webDomainTokens, threshold: BeeFreeModel.shared.thresholdToDiscourage ) ] let center = DeviceActivityCenter() do { print("Try to start monitoring...") // Call startMonitoring with the activity name, schedule, and events try center.startMonitoring(.daily, during: schedule, events: events) } catch { print("Error monitoring schedule: ", error) } } } // APP class BeeFreeModel: ObservableObject { // Import ManagedSettings to get access to the application shield restriction let store = ManagedSettingsStore() //@EnvironmentObject var store: ManagedSettingsStore @Published var selectionToDiscourage: FamilyActivitySelection @Published var thresholdToDiscourage: DateComponents @Published var setOfApps: [String] init() { selectionToDiscourage = FamilyActivitySelection() thresholdToDiscourage = DateComponents() var setOfAppIdentifiers: Set<String?> = Set<String?>() setOfApps = [String]() if selectionToDiscourage.applicationTokens.isEmpty {} else { for application in BeeFreeModel.shared.selectionToDiscourage.applications { setOfAppIdentifiers.insert(application.localizedDisplayName) setOfApps = setOfAppIdentifiers.compactMap { $0 }.sorted() } } } class var shared: BeeFreeModel { return _BeeFreeModel } func setSelection() { let applications = BeeFreeModel.shared.selectionToDiscourage } func changeThreshold(threshold: DateComponents) { thresholdToDiscourage = threshold } } // APP /// ... Button("Select Apps to Discourage") { isDiscouragedPresented = true } .familyActivityPicker(isPresented: $isDiscouragedPresented, selection: $model.selectionToDiscourage) } .onChange(of: model.selectionToDiscourage) { BeeFreeModel.shared.setSelection() } // ... // ... Button("Save Time") { saveTime() let new_threshold = DateComponents(hour: savedTime?.hours, minute: savedTime?.minutes, second: savedTime?.seconds) model.changeThreshold(threshold: new_threshold) } } .onChange(of: model.thresholdToDiscourage) { BeeFreeSchedule.setSchedule() // ... I believe I am using the latest stable version of Xcode (recently deleted and reinstalled). I'm really new to mobile development to Swift so any help is greatly appreciated. Thank you! :)
Posted
by
Post not yet marked as solved
1 Replies
296 Views
At 11:37 in this video - https://developer.apple.com/videos/play/wwdc2021/10123/ - Nolan instantiates MyModel() in swiftui view file. And then at 12:02 he just uses MyModel from extension. I have the exact same code and when I try to build my project, it fails with error that MyModel() could not be found. I shared my MyModel.swift file between extension target and main app. Now it builds. However, it seems there are two separate instances of MyModel. What is proper way for DeviceActivityMonitor extension to pass data to main app? I simply want to increment counter from extension every minute and let the main app to know that. Or even better, - is there a way to use SwiftData from Device Activity Monitor extension?
Posted
by
Post not yet marked as solved
1 Replies
245 Views
I am 17, almost 18 years old and still have screen time restrictions on my phone. My downtime every night turns off at midnight, then later turns back on at 7:30 am. Last night I plugged in my phone to go to bed and when I woke up it says that instagram was being used for 4 1/2 hours from 2am to 7am. This is impossible because of my downtime restrictions and now I have no time left on my apps for the day. Does anyone know how to fix this?
Posted
by