Prevent access to the Screen Time API without guardian approval and provide opaque tokens that represent apps and websites.

All subtopics
Posts under Family Controls topic

Post

Replies

Boosts

Views

Activity

Unable to Use DeviceActivityReport to Show Screen Time in App
Hi team. I am working on an app that uses the Screen Time API. I got access to the family controls (distribution) capability through the request process for my main app. I added a DeviceActivityReport extension in XCode, but haven't been able to get the extension to show up on the screen. I noticed that the extension only has the development version of the family controls capability available. Is this the source of my errors? I was able to get the screen time displayed in a test app I built where both the main app and extension used the development version of the capability, which led me to believe that discrepancy could be the issue. Let me know if there is anything I can provide to help in the debugging process. I didn't send a minimal example in this request due to the fact that I would have to remove most of my functionality to create a "minimal" example (since the signing is only for my main app), but I can do that if needed. Thanks! I looked through the logs in the console for the phone (I'm testing on a real iPhone 13 Pro Max), but didn't see anything that popped out after looking (not exactly sure what to look for though). STEPS TO REPRODUCE: Create an app with the Family Controls, Distribution capability. Then create the DeviceActivityReport with the Family Control, Development capability. Attempt to see the DeviceActivityReport in the main app. NOTE: I was successfully able to create a minimal test app completely separately that used the Development versions of the capabilities for both with the exact same extension code. That's why I think the issue could be due to the capability version discrepancy.
5
0
420
Jan ’25
Issues with ApplicationTokens After Transferring an App Using FamilyControls Framework
I am encountering an issue after transferring an app that uses the FamilyControls framework to a different app account. After releasing a new version of the app post-transfer, the following problems arose: ApplicationTokens obtained in the pre-transfer version no longer function when used with ManagedSettingsGroup.ShieldSettings in the post-transfer version. Using the same ApplicationTokens with Label(_ applicationToken: ApplicationToken) does not display the app name or icon. These issues did not occur in the pre-transfer version and everything worked as expected. We suspect that ApplicationTokens obtained prior to the transfer are no longer valid in the updated app released under the new app account. We are seeking guidance on the following: Is this expected behavior after transferring an app to another app account? What steps should we take to ensure that ApplicationTokens obtained before the transfer remain functional in the post-transfer environment? If these tokens are invalidated due to the transfer, what are the recommended procedures for regenerating or updating ApplicationTokens for existing app users? Maintaining a seamless user experience after transferring the app is critical. We would greatly appreciate any insights or guidance. Please let us know if additional information or logs would assist in investigating this issue. Thank you!
2
1
531
Jan ’25
ManagedSettingStore limits and groups
So what's the point of being able to block unto 50 apps per ManagedSettingStore via store.application.blockedApplications (which works fine) until removing the blocked apps or clearing the store. Where the following occurs if you have a social networking group with more than 9 apps only 9 apps will go back into the group and all the others will go onto the springboard all jumbled if you end up with an empty group then tap into the group, it is removed then during the reset all apps are placed back on to the springboard
0
0
340
Jan ’25
Any workaround for expanding a large category in FamilyActivityPicker?
I’m developing a self-management app using Family Controls, but I’ve encountered a FamilyActivityPciker's crash due to an XPC(or UIRemoteView) issue when there are too many tokens(maybe 200+ items) in a category. This makes bad UX, so I’m looking for a workaround. (I guess that the crash reason is cross process memory limitations, such as App Extension 50MB memory limitation.) A lot of web domains contribute to increase the number of tokens, However, even after clearing Safari’s browsing history, the tokens displayed in the FamilyActivityPicker remains unchanged. Is there any workaround that a 3rd party developer can implement to address this issue? prevent FamilyActivityPicker crashes or reduce the number of web domain tokens? For example, if there’s a way to reset the web domain tokens shown in FamilyActivityPicker from the Settings app, I could offer a help to users. Does anybody have ideas? Expanding SNS Category (29 items) It succeeded. Expanding Productivity & Finance (214 items) It failed. The screen froze, then appears blank. When the number of items is around 100, the crash rate is 50%, but when the items are over 200, the crash rate is 100%. Search Bar Problem The search bar also has same problem. If the number of search results are small, it works good without any blank, but if there are a lot of search results (200+), the XCP crashes and the screen appears blank. Code to Reproduce import SwiftUI import FamilyControls struct ContentView: View { @State private var selection = FamilyActivitySelection() @State private var isPickerPresented: Bool = false var body: some View { VStack { Button("Open Picker") { isPickerPresented = true } } .familyActivityPicker(isPresented: $isPickerPresented, selection: $selection) } } Steps to Reproduce Prepare a category that has 200+ items Try to open the category in the picker The screen will freeze, then appears blank. Errors in Console [u EDD60B83-5D2A-5446-B2C7-57D47C937916:m (null)] [com.apple.FamilyControls.ActivityPickerExtension(1204)] Connection to plugin interrupted while in use. AX Lookup problem - errorCode:1100 error:Permission denied portName:'com.apple.iphone.axserver' PID:2164 ( 0 AXRuntime 0x00000001d46c5f08 _AXGetPortFromCache + 796 1 AXRuntime 0x00000001d46ca23c AXUIElementPerformFencedActionWithValue + 700 2 UIKit 0x0000000256b75cec C01ACC79-A5BA-3017-91BD-A03759576BBF + 1527020 3 libdispatch.dylib 0x000000010546ca30 _dispatch_call_block_and_release + 32 4 libdispatch.dylib 0x000000010546e71c _dispatch_client_callout + 20 5 libdispatch.dylib 0x00000001054765e8 _dispatch_lane_serial_drain + 828 6 libdispatch.dylib 0x0000000105477360 _dispatch_lane_invoke + 408 7 libdispatch.dylib 0x00000001054845f0 _dispatch_root_queue_drain_deferred_wlh + 328 8 libdispatch.dylib 0x0000000105483c00 _dispatch_workloop_worker_thread + 580 9 libsystem_pthread.dylib 0x0000000224f77c7c _pthread_wqthread + 288 10 libsystem_pthread.dylib 0x0000000224f74488 start_wqthread + 8 ) Error acquiring assertion: <Error Domain=RBSAssertionErrorDomain Code=2 "Specified target process does not exist" UserInfo={NSLocalizedFailureReason=Specified target process does not exist}>
7
5
2.3k
Feb ’25
DeviceActivityMonitor extension does not call back at the set time
Hello Apple development team, I have developed an App for screen time management, which mainly uses ScreenTimeAPI. Users can set certain Apps to be disabled during a certain period of time. After the App is released, users often report that the settings do not take effect as expected. I have seen many developers on the forum reporting that the DeviceActivityMonitor extension sometimes does not trigger callbacks. Based on this background, I have the following questions: Is it a known problem that the DeviceActivityMonitor extension sometimes does not trigger callbacks? If so, are there any means to avoid or reduce the probability of occurrence? In addition to being killed by the system when the running memory exceeds (I just called some ScreenTimeAPI and accessed UserDefaults in the extension, which should not exceed the running memory), under what other circumstances will the DeviceActivityMonitor extension be killed by the system? Will it automatically recover after being killed? Will some callbacks be called when killing? Does ManagedSettingsStore have a life cycle? How do you avoid conflicts when configuring the underlying operating mechanism of multiple stores? This is a random problem. I have never encountered it during development and debugging, but users often report it. thanks
1
0
533
Feb ’25
Device Activity Report only for Selected Apps
I want to display device activity reports for particular selected apps. for getting a daily basis app uses time. Now, what is happening? there are 10 apps selected from the family activity picker but some apps are displayed in the list. I need all 10 apps or more that I will choose from the family activity picker. The bellow code is used for fetching reports. var body: some View { VStack { DeviceActivityReport(context, filter: filter) } } bellow code is used for the filter @State public var filter = DeviceActivityFilter() init(selectedApps: Set<ApplicationToken>, selectedCategories: Set<ActivityCategoryToken>, selectedWebDomains: Set<WebDomainToken>) { self.selectedApps = selectedApps self.selectedCategories = selectedCategories self.selectedWebDomains = selectedWebDomains self.filter = DeviceActivityFilter( segment: .daily( during: Calendar.current.dateInterval( of: .weekOfYear, for: .now )! ), users: .all, devices: .init([.iPhone]), applications: selectedApps, categories: selectedCategories, webDomains: selectedWebDomains ) } You can see we selected 3 apps from family activity picker but we getting 2 apps from DeviceActivityReport extension following code is for device activity report extension let context: DeviceActivityReport.Context = .totalActivity // Define the custom configuration and the resulting view for this report. let content: (ActivityReport) -> TotalActivityView func makeConfiguration(representing data: DeviceActivityResults<DeviceActivityData>) async -> ActivityReport { // Reformat the data into a configuration that can be used to create // the report's view. var res = "" var list: [AppDeviceActivity] = [] let totalActivityDuration = await data.flatMap { $0.activitySegments }.reduce(0, { $0 + $1.totalActivityDuration }) for await d in data { res += d.user.appleID!.debugDescription res += d.lastUpdatedDate.description for await a in d.activitySegments{ res += a.totalActivityDuration.formatted() for await c in a.categories { for await ap in c.applications { if let apptoken = ap.application.token { let appName = (ap.application.localizedDisplayName ?? "nil") let bundle = (ap.application.bundleIdentifier ?? "nil") let duration = ap.totalActivityDuration let numberOfPickups = ap.numberOfPickups let app = AppDeviceActivity(appToken: apptoken, id: bundle, displayName: appName, duration: duration, numberOfPickups: numberOfPickups) list.append(app) } } } } } return ActivityReport(totalDuration: totalActivityDuration, apps: list) }
4
0
1k
Feb ’25
DeviceActivityMonitor.intervalDidEnd never getting called
I'm trying to build an app with a DeviceActivityMonitor extension that executes some code after 15 minutes. I can confirm that the extension is set up correctly and that intervalDidStart is executed, but for some reason the intervalDidEnd method never gets called. What I'm doing in both is just registering a local notification. class DeviceActivityMonitorExtension: DeviceActivityMonitor { let store = ManagedSettingsStore() override func intervalDidStart(for activity: DeviceActivityName) { createPushNotification( title: "Session activated!", body: "" ) super.intervalDidStart(for: activity) } override func intervalDidEnd(for activity: DeviceActivityName) { createPushNotification( title: "Session ended", body: "" ) super.intervalDidEnd(for: activity) } private func createPushNotification(title: String, body: String) { let content = UNMutableNotificationContent() content.title = title content.body = body // Configure the recurring date. var dateComponents = Calendar.current.dateComponents([.era, .year, .month, .day, .hour, .minute, .second], from: Date().addingTimeInterval(1.0)) dateComponents.calendar = Calendar.current dateComponents.timeZone = TimeZone.current // Create the trigger as a repeating event. let trigger = UNCalendarNotificationTrigger(dateMatching: dateComponents, repeats: false) let uuidString = UUID().uuidString let request = UNNotificationRequest(identifier: uuidString, content: content, trigger: trigger) // Schedule the request with the system. let notificationCenter = UNUserNotificationCenter.current() notificationCenter.add(request) } } And this is the method that is starting the monitoring session: @objc public static func startSession() -> String? { // Calculate start and end times let center = DeviceActivityCenter() let minutes = 15 let startDate = Date().addingTimeInterval(1) guard let endDate = Calendar.current.date(byAdding: .minute, value: minutes, to: startDate) else { return "Failed to create end date?" } // Create date components and explicitly set the calendar and timeZone let startComponents = Calendar.current.dateComponents([.era, .year, .month, .day, .hour, .minute, .second], from: startDate) let endComponents = Calendar.current.dateComponents([.era, .year, .month, .day, .hour, .minute, .second], from: endDate) // Create schedule let schedule = DeviceActivitySchedule( intervalStart: startComponents, intervalEnd: endComponents, repeats: false ) print("Now", Date()) print("Start", startDate, startComponents) print("End", endDate, endComponents) print(schedule.nextInterval) do { // Use a consistent activity name for our simple implementation let activity = DeviceActivityName("SimpleSession") try center.startMonitoring(activity, during: schedule) return nil } catch { return "Failed to start monitoring: \(error)" } } I can confirm my dates & date components make sense with the 4 print statements. Here is the output: Now 2025-02-12 04:21:32 +0000 Start 2025-02-12 04:21:33 +0000 era: 1 year: 2025 month: 2 day: 11 hour: 20 minute: 21 second: 33 isLeapMonth: false End 2025-02-12 04:36:33 +0000 era: 1 year: 2025 month: 2 day: 11 hour: 20 minute: 36 second: 33 isLeapMonth: false Optional(2025-02-12 04:21:33 +0000 to 2025-02-12 04:36:33 +0000) I get the Session activated! notification but never get the Session ended notification. Half an hour later, I've tried debugging the DeviceActivityCenter by printing out the activities property and can see that it is still there. When I try to print out the nextInterval property on the schedule object i get from calling center.schedule(for:), it returns nil. I'm running this on an iPhone 8 testing device with developer mode enabled. It has iOS 16.7.10. I'm totally lost as to how to get this to work.
1
0
393
Feb ’25
Family Controls (Distribution) was granted to main bundle ID, but not to the extensions
I've successfully obtained Distribution entitlements for Family Controls. However, this seems to only apply to the main target/identifier and not the extensions, like DeviceActivityMonitor, ShieldConfigurationDataSource, or ShieldActionExtension. Did I perhaps fill out the form with the wrong bundle ID? If I go to "Certificates, Identifiers & Profiles", my main identifier for the app has the Distribution entitlement. But the extensions and the wildcard don't. This means that trying to create an archive results in the following two errors, each repeated twice: Provisioning profile failed qualification (Profile doesn't support Family Controls (Development)) Provisioning profile failed qualification (Profile doesn't include the com.apple.developer.family-controls entitlement) Note that my entitlement files are set up correctly. Do I need to fill out the form with a wildcard instead? Or am I doing something wrong? Thank you.
3
0
714
Feb ’25
Detect change to apps Screen Time Access
I'm creating an app which gamifies Screen Time reduction. I'm running into an issue with apples Screen Time setting where the user can disable my apps "Screen Time access" and get around losing the game. Is there a way to detect when this setting is disabled for my app? I've tried using AuthorizationCenter.shared.authorizationStatus but this didn't do the trick. Does anyone have an ideas?
0
0
422
Feb ’25
Related WebDomain Token is automatically blocked, but how do we know the related ManagedSettingsStore?
I have noticed that when I select the app token of the youtube app to be blocked via a ManagedSettingsStore, the youtube website is blocked as well (which is a good and intended behavior IMO). But how do I know in the ShieldConfigurationDataSource’s override func configuration(shielding webDomain: WebDomain, in category: ActivityCategory) -> ShieldConfiguration to which ManagedSettingsStore the WebDomain’s token is related? We use different ManagedSettingsStores for different block purposes, which differentiate in their ShieldConfiguration. Thanks a lot and have a great day!
2
0
487
Feb ’25
Pre-approval for Family Controls Entitlement?
Hi there, I am planning an app that requires use of the Family Controls Entitlement to access data on the user's screen time. I understand that this has to be requested from Apple before it can be used in production. I have found the following form to request approval, but it requires an App and bundle ID, which suggests that approval can only be requested after the app has been developed. https://developer.apple.com/contact/request/family-controls-distribution I'd like to avoid the situation where I spend a lot of time on developing the app, only to find out that the Family Controls Entitlement will not be granted for my use case. Is there any way that I can request provisional pre-approval for my app? Perhaps based on an app description and some mockups? Or, at least some idea of whether my particular use case is likely to be approved? Thanks.
1
0
470
Feb ’25
Waiting Forever for iOS Family Controls Entitlement
I'm at my wit's end here with an iOS app I'm developing. I've applied for the Family Controls entitlement, and while my extensions (like Device Monitor) have been accepted, the main target entitlement for my app still hasn't been approved. Here's the timeline: Extensions (Device Monitor etc.): Accepted about a month ago. Main App Entitlement: Still pending - it's been over 6 weeks now. I'm looking for: Anyone who has gone through this process and can share how long it took for their main app entitlement to get approved after the extensions were. Any tips on what might speed up the process or what I might be doing wrong. Experiences with contacting Apple Developer Support regarding this issue. If you've been through a similar ordeal or have any advice, I'd really appreciate it. Thanks for any help or insight you can offer!
1
1
348
Feb ’25
Unblocking Apps After a Scheduled Duration in FamilyControl
I am able to block apps using FamilyControl and Shield. Unblocking is also simple—just assign nil to store.shield.applications. However, I want to unblock them even when the app is not open. Use case: Let's say the app allows users to create a session where a particular app is blocked for a specific duration. Once the session starts, the app should remain blocked, and as soon as the session time ends, it should automatically be unblocked. Please help me with this. Thank you!
0
0
435
Feb ’25
Guidance on Upgrading to Production Access for Screen Time API
Hello everyone, I’m currently developing an app that uses the Family Controls API, specifically the Screen Time API. However, my current entitlement is limited to development mode, which prevents me from publishing my app on TestFlight. I have already contacted Apple Developer Support for production access but wanted to reach out to the community as well and I was referenced to FamilyControls API documentation and I couldn't find anything related to my case. Has anyone successfully upgraded their entitlement from development-only to production? Any insights on the process, tips for communicating with Developer Support, or guidance on ensuring full compliance with the Family Controls guidelines would be extremely helpful.
0
0
311
Mar ’25
DeviceActivityReport view fails to render until it's repeatedly added to the view hierarchy
The DeviceActivityReport view does not render immediately when added to the view hierarchy. Instead, it requires repeated navigation to the screen hosting the DeviceActivityReport view for it to appear. Furthermore, there is no programmatic way to determine whether the view is being rendered for the user, leading to an inconsistent and often poor user experience. I've created a sample project that demonstrates the issue.
2
1
455
Mar ’25