I've submitted several requests for Family Controls Distribution access for all of my app targets over two weeks ago and have not gotten any response. The app I've been working on for over a year is finally ready to beta test to 200+ waitlisted users but this final roadblock is killing me! Anyone know what to do? Is there anyone else I could reach out to other than the apple request form to get help with this? Thank you!
Screen Time
RSS for tagShare and manage web-usage data, and observe changes made to Screen Time settings by a parent or guardian.
Posts under Screen Time tag
141 Posts
Sort by:
Post
Replies
Boosts
Views
Activity
I want to create an app to control a child's device. As I understand it, I need to follow this logic:
I have one app for both the child and the parent.
For the child, I request authorization with the following code:
try await AuthorizationCenter.shared.requestAuthorization(for: .child)
For the parent, I show functions like:
familyActivityPicker
Are these settings automatically applied to the child's device, or do I need to send a silent push notification to apply the new settings? Additionally, how can I get statistics from the child's device to the parent's device?
Topic:
App & System Services
SubTopic:
General
Tags:
Device Activity
Managed Settings
Family Controls
Screen Time
Hi everyone,
I’m developing a parental control app using Apple's ScreenTime API, and I need to display ScreenTime data separately for each child in a family. The API offers options like .children and .all, but I’m looking for the best way to reliably filter and show data for a single child within the app.
I’ve seen other apps like Ohana successfully implement this feature, even the apple official family screen time feature has this where parents can view ScreenTime data for each child individually. I want to achieve a similar experience in my app, ensuring that if a parent selects "John," the app only displays John's ScreenTime, without mixing in data from his siblings.
Here’s the approach I’m considering using DeviceActivityFilter and DeviceActivityReport to target data for a specific child:
let filter = DeviceActivityFilter(
segment: .children,
intervals: .everyDay
)
let report = DeviceActivityReport(
filter: filter
) { (data) in
// Process and separate data for each child
if let activityData = data as? DeviceActivityReportData {
for child in activityData.children {
if child.name == "ChildName" { // Replace "ChildName" with the actual child's name or identifier
// Access and display data for the specific child
print("Child: \(child.name), Screen Time: \(child.screenTime)")
}
}
}
}
Context:
Goal: I need to ensure parents can view ScreenTime data for each child individually, similar to how Ohana does it. For example, selecting "John" should display only John's ScreenTime.
Challenge: While some data can be grouped within the DeviceActivity extension, I'm not entirely sure if this approach with DeviceActivityFilter is the most reliable way to isolate and display data for a single child.
Has anyone implemented a similar solution? Are there any alternative methods or best practices that could improve the accuracy and reliability of this filtering?
Any advice or examples would be greatly appreciated!
Thanks!
Hello! I've been doing a lot of work with ApplicationTokens, but there is very little documentation. While Apple gives you the FamilyAcitvitiesPicker to get tokens of apps on an iPhone, I need to get the tokens of apps that aren't on the phone.
Example:
Someone can select Instagram even though they don't have it downloaded. Then the application token will get sent to a server. Then a different person who does have Instagram on their phone will receive the token and it will do something with that application.
Because FamilyActivitiesPicker can only select apps on the iPhone that it is running on, FamilyActivitiesPicker is useless to me, leading to my problem:
Creating an ApplicationToken without FamilyActivitiesPicker
This documentation says that I can create an Application (and thus an ApplicationToken) from the bundle identifier
init(bundleIdentifier: String)
Creates an object that represents the app with the specified bundle
identifier.
However, when I try to use this to get instagrams(or any apps) token, it returns nil every time!
So, finally, my questions:
How do I correctly use this initializer to create an ApplicationToken?
Or, if this won't work for my purposes
Are the ApplicationTokens created by FamilyActivitiesPicker the same across all devices no matter what?
Topic:
App & System Services
SubTopic:
General
Tags:
SwiftUI
Managed Settings
Family Controls
Screen Time
Hello. I’m building an app that would use the Screen Time API to restrict apps on the users phone at set times and also give Device usage reports and analysis to the user. Do I need to request permission from apple to do this? If no, then what applications of the API require getting permission from Apple?
I've been using DeviceActivityMonitor for 2 years, and recently noticed the following issue, starting in iOS 17.5 (another user also reported here).
For a sizable percentage of my users, device activity event thresholds get triggered together. My app sends notifications for every hour of screen time during the DeviceActivitySchedule using event thresholds. Often users will get, for example, the 1, 2, and 3 hour screen time notifications all at the same time.
I have a hypothesis for why this is happening: the system sometimes terminates the app extension for various reasons, one being if the 6MB memory limit is reached. It seems as though the retry policy is to retry the failed threshold at the next event threshold. And if the following threshold also fails, they can pile up until the next one succeeds. I think this is a new retry policy since iOS 17, and I believe this because:
There used to be a bug where the same threshold was triggered multiple times in a row, indicating that the failed threshold was retried immediately. This bug is no longer around and it's been replaced by the one I am reporting.
According to my logs, thresholds that get triggered together are also called earlier when they are supposed to be called - but the callback function does not complete. So this indicates that the threshold isn't just called late, but that it is called once and then retried again later.
If anyone could answer the following questions I'd be super grateful:
Is there ANY way to log when the system terminates the app extension and for what reason? And not just on my own device, but for all our users in production (because it's hard to reproduce this issue, as it only happens for some portion of our users). Maybe some kind of crash report or failure callback that will allow my to ping my server?
Could anyone at Apple could confirm my hypothesis about the new retry policy causing this issue?
My app correctly applies the ShieldConfiguration template that I chose (icon, text, CTA, etc), but some users reported seeing the following default shield:
With the default shield text that reads, "You cannot use AppName because it is restricted."
Any idea why?
Hi everyone,
I’m encountering an issue with shield.applicationCategories = .all(except: applications.applicationTokens) when trying to shield all apps except a specified few. Despite using this configuration, all apps are getting shielded, including those that should be exempt.
I’ve verified that the correct applicationTokens are being used and ensured that there are no conflicting schedules that might override this configuration. Interestingly, the ShieldConfiguration appears for the apps that are supposed to be blocked, but not for the ones in the exception list.
Has anyone else experienced this issue, or does anyone have insights into what might be causing this behavior?
Thanks in advance!
Topic:
App & System Services
SubTopic:
General
Tags:
Device Activity
Managed Settings
Family Controls
Screen Time
Quibr question for Apple -
Context: We are developing an app that via screentime access blocks restricted sites for gamblers. However our blocking can be bypassed by going into settings→screentime->Apps With Screen time access" and toggling off access to screentime with device’s FaceID (and not the screentime passcode.) Then they can browse whatever blocked site and delete our app if they wish.
Question: We would like to know if there is a way to get the information when and how many times the toggle of our app under the “Apps with screen time access” has been pressed, or its current status.
3rd waay:
Alternatively is there a way to monitor if the app is still installed on the device?
Hey everyone,
I'm working on implementing an AppLimit, where after accumulating x minutes of Screen Time for an app, it should be blocked. It works fine on the first day, but stops functioning correctly on subsequent days.
What I'm Doing
I start a 24/7 schedule with a DeviceActivityEvent that has a specified Screen Time threshold.
In my DeviceActivityMonitor, I'm reacting to the eventDidReachThreshold. Once the accumulated time is reached, the app is blocked. This works as expected on the first day.
Issues I'm Experiencing / Questions
Second Day Issue: On the second day, the app is no longer blocked after the Screen Time threshold is reached, even though it worked on the first day. This leads me to suspect that a DeviceActivityEvent is "consumable". Is this correct?
Pre-existing Screen Time Issue: If a user has already surpassed the Screen Time threshold before monitoring starts, the app isn't blocked once the schedule is set up. This leads to 2 issues:
I would expect that the accumulated amount of time after starting the schedule would result in the call of eventDidReachThreshold. But it is never called
It could also be the case that the previously accumulated time is being kept in mind, but that would mean the apps should be blocked, which isn't the case.
Does the threshold account for accumulated Screen Time before the schedule begins? I haven't tested setting a limit of 10 minutes, accumulating 3 minutes of Screen Time, then starting the schedule and accumulating the remaining time, but I'm curious if anyone has encountered this behavior.
Does anyone have an explanation for this behavior? Any help would be greatly appreciated!
Topic:
Programming Languages
SubTopic:
Swift
Tags:
Device Activity
Managed Settings
Family Controls
Screen Time
Hi everyone,
I'm trying to find out if there's a way to mock Screen Time for a specific app (either on a real device or in a simulator). Specifically, I need to set the usage time of an app to something like 15 minutes. I'm not looking to alter the total Screen Time, just the usage time for a single app.
Currently, I'm manually keeping the app open for 15 minutes before I can start testing to see if the desired behavior occurs, but this process is slow and frustrating. Unfortunately, I can't reduce the 15-minute threshold, as Apple doesn't allow it for this particular use case.
Any advice or solutions would be greatly appreciated!
Hello Apple Developer Community,
We have developed two totally separate apps for parental control: one for parents (xyz/parent.com) and one for children (abc/child.com). These are not two sides of the same app, but rather distinct applications. Recently, we integrated these two apps and encountered a few challenges and questions that we hope the community can help with.
Family Picker Behavior: We noticed that only the parent app on the current device is displayed in the Family Activity Picker. Is this the intended behavior? Our expectation was that the Family Activity Picker would show both the parent and child apps available on the device. Is there a way to ensure that both types of apps are listed?
Filtering Apps in Family Picker: Is it possible to filter the apps displayed in the Family Activity Picker to show only the child’s app and exclude the parent app? Our goal is to streamline the selection process for users by removing irrelevant apps from the picker. If direct filtering is not possible, are there any recommended workarounds or best practices to achieve a similar result?
Screen Time Permission Requirements: We’ve successfully implemented screen time permissions using the Authorization Center for the child app. However, do we also need to request screen time permissions from within the parent app? If so, are there any specific guidelines or best practices for managing screen time permissions across two interconnected apps?
Triggering Child Managed Settings from Multiple Apps: Is it feasible to trigger managed settings (e.g., enabling restrictions) for the child app from both the parent and child apps? We want to ensure consistent enforcement of settings regardless of which app initiates the change. Are there any limitations or conflicts we should be aware of when managing settings from two different apps?
We appreciate any guidance or insights you can provide on these issues. We’ve referred to the Family Controls and Screen Time documentation, but we're seeking more specific advice related to the integration of two separate apps in this context.
Thank you in advance for your help!
Hi everyone,
I'm currently working with the Screen Time API, specifically trying to figure out the best way to pause an active, repeating schedule without disrupting future schedules. Here's the scenario:
I have a repeating schedule set from 10:00 AM to 8:00 PM daily. If I need to pause the schedule temporarily, my current approach involves stopping monitoring, clearing all restrictions, and then setting a new schedule for the remaining time after the pause. However, this method cancels the repeating schedule entirely, which causes issues when the schedule is supposed to restart the next day at 10:00 AM. Instead, it starts after the pause time, which isn’t what I want.
Challenges I'm Facing:
Maintaining Repeating Schedules:
How can I pause the schedule in a way that ensures it resumes correctly the next day at the intended time (10:00 AM)?
DeviceActivityMonitor Logic:
Is there a way to deactivate and reactivate the schedule through the DeviceActivityMonitor without fully stopping the monitoring? Ideally, I'd like to retain the original schedule, pause it, and then resume it seamlessly after the pause.
What I’ve Tried So Far:
I’ve attempted to store the necessary data in the App Groups shared container as a local file. In the DeviceActivityMonitor, I used the schedule's name to identify and retrieve the saved object, planning to use this data to reapply the shielding after the pause. Unfortunately, this approach exceeds the 6MB memory limit of the extension, which is another roadblock.
Given these issues, I’m unsure how to move forward. Are there any best practices or alternative approaches that could help manage this situation more effectively? Any insights or suggestions would be greatly appreciated!
Thanks in advance for your help.
Hello! I'm currently making an app that requires the ability to activate a screenlock for a point in the future. I currently have my project setup so that I can set a screenlock through a DeviceActivityMonitorExtension (DAM) but regardless of the time interval I use for intervalDidStart and intervalDidEnd the screenlock just seems to apply instantly. I'm under the impression that I'm missing something outside of just passing the interval to the DAM functions. Has anyone accomplished this? Thank you!
Hi everyone,
I'm working on an app that uses the Screen Time API, and I'm encountering an issue with Live Activities.
The app runs a timer (e.g., 10 minutes), after which the intervalDidEnd method in DeviceActivityMonitor is triggered. To improve the user experience, I've implemented Live Activities to display the remaining time.
However, I'm having trouble stopping the Live Activity when the timer expires and intervalDidEnd is called. It seems that the Screen Time
extensions cannot detect or interact with active Live Activities, even though
both share the same App Group.
My Question:
Since the DeviceActivityMonitor extension does not seem to be able to detect Live Activities, does anyone know if there’s a way to end a Live Activity when the timer expires without relying on a server? Using Apple’s Push Notification service feels excessive given the lightweight nature of the app, which doesn’t use server-side components.
Any insights or suggestions would be greatly appreciated!
Thanks!
Topic:
Programming Languages
SubTopic:
Swift
Tags:
WidgetKit
ActivityKit
Family Controls
Screen Time
Is there an API for obtaining the screen usage time of each app on the iPhone development platform
Hello,
We are developing a parental control app consisting of two parts: a parent app to manage settings and a child app to enforce these settings using iOS's Screen Time API, CoreData, and other components. We've attempted to use silent notifications with Firebase Cloud Messaging (FCM) to communicate updates from the parent app to the child app. Our current implementation involves background modes for remote messages and background tasks.
However, we're facing a challenge: while normal FCM push notifications with a 'message' key work as expected, silent notifications (with only a 'data' key) do not trigger the desired behavior in the child app, even though FCM returns a success response.
We're looking for assistance with two main issues:
Alternative Approaches: Is there a better way to notify the child app of changes? We're considering a system where the child app periodically checks for updates via API and then updates CoreData and managed settings. Any recommendations for this architecture or a more reliable notification system would be greatly appreciated.
Debugging Silent Notifications: If our current approach using silent notifications is feasible, could someone help us debug why these notifications are not working as expected? We've been stuck on this for a week, and any help would be a lifesaver.
Here's the relevant part of our AppDelegate code:
import UIKit
import FirebaseCore
import FirebaseMessaging
import BackgroundTasks
@objc class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {
let gcmMessageIDKey = "gcm.message_id"
let backgroundTaskIdentifier = "com.your-company.your-app.silentnotification"
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
FirebaseApp.configure()
Messaging.messaging().delegate = self
// Register for remote notifications
UNUserNotificationCenter.current().delegate = self
application.registerForRemoteNotifications()
// Register background task
BGTaskScheduler.shared.register(forTaskWithIdentifier: backgroundTaskIdentifier, using: nil) { task in
self.handleBackgroundTask(task: task as! BGProcessingTask)
}
return true
}
// Handle incoming remote notifications
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any],
fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
if let aps = userInfo["aps"] as? [String: Any],
let contentAvailable = aps["content-available"] as? Int, contentAvailable == 1 {
// This is a silent notification
handleSilentNotification(userInfo: userInfo, completionHandler: completionHandler)
} else {
// This is a regular notification
Messaging.messaging().appDidReceiveMessage(userInfo)
completionHandler(.newData)
}
}
// Handle silent notification
func handleSilentNotification(userInfo: [AnyHashable: Any], completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
let request = BGProcessingTaskRequest(identifier: backgroundTaskIdentifier)
request.requiresNetworkConnectivity = true
do {
try BGTaskScheduler.shared.submit(request)
performAPICall { result in
switch result {
case .success(_):
completionHandler(.newData)
case .failure(_):
completionHandler(.failed)
}
}
} catch {
completionHandler(.failed)
}
}
// Handle background task
func handleBackgroundTask(task: BGProcessingTask) {
task.expirationHandler = {
task.setTaskCompleted(success: false)
}
performAPICall { result in
task.setTaskCompleted(success: result != nil)
}
}
// Perform API call (placeholder implementation)
func performAPICall(completion: @escaping (Data?) -> Void) {
// Your API call implementation here
// For testing, you can use a simple delay:
DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
completion(Data())
}
}
}
extension AppDelegate: MessagingDelegate {
func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String?) {
print("FCM token: \(fcmToken ?? "nil")")
// TODO: Send this token to your server
}
}
Additionally, here is how we're sending notifications from the server side using Node.js:
// Import the required Firebase Admin SDK (assumed to be initialized elsewhere)
// const { getMessaging } = require('firebase-admin/messaging');
/**
* Sends a background push notification to an iOS device
* @returns {Promise<string>} The message ID if successful
* @throws Will throw an error if the sending process fails
*/
async function sendBackgroundPushNotification() {
// Construct the message object for a background push notification
const message = {
apns: {
headers: {
// Set the priority of the push notification
"apns-priority": "5",
priority: "5",
// Indicate that this is a background refresh notification
"content-available": "1",
content_available: "1",
// Specify the push type as background
"apns-push-type": "background",
// Set the topic to your app's bundle identifier
"apns-topic": "com.your-company.your-app", // Replace with your actual bundle identifier
},
payload: {
aps: {
// This tells iOS to wake up your app in the background
"content-available": 1,
},
},
},
// Custom data payload to be sent with the notification
// Modify this object to include the data you want to send
data: {
// Add your custom key-value pairs here
},
// Uncomment the following block if you want to include a visible notification
// notification: {
// title: "Notification Title",
// body: "Notification Body",
// },
token
token: "DEVICE_FCM_TOKEN_PLACEHOLDER",
};
try {
// Attempt to send the message using Firebase Cloud Messaging
const response = await getMessaging().send(message);
console.log("Successfully sent background data to iOS:", response);
return response;
} catch (error) {
console.error("Error sending background data to iOS:", error);
throw error;
}
}
// Example usage:
// sendBackgroundPushNotification()
// .then((response) => console.log("Message sent successfully:", response))
// .catch((error) => console.error("Failed to send message:", error));
We would really appreciate any insights or guidance on these issues. Thank you!
Topic:
App & System Services
SubTopic:
Notifications
Tags:
APNS
User Notifications
Family Controls
Screen Time
I shield a web domain picked by users like this (discouragedSelections is an instance of FamilyActivitySelection() btw) :
let webDomainTokens = discouragedSelections.webDomainTokens
store.shield.webDomains = webDomainTokens
The domain is correcly shielded and I can see the restricted screen when I access it via Safari.
When I tap on the main button of that restricted view, I receive a different token than the one I got from .webDomainTokens from the code above. Why?
override func handle(action: ShieldAction, for webDomain: WebDomainToken, completionHandler: @escaping (ShieldActionResponse) -> Void) {
// webDomain here is different from the one in store.shield.webDomains
}
Hello,
I installed the iPadOS 18 PB 1 on my iPad Pro M4 a few days ago and noticed a bug which is annoying.
If screen time runs out, the first thing I noticed, is that it is no longer possible to get one more minute in an app and also to send a message to the guard.
If I open the screen time settings, it will freeze and forces me to force quit the settings.
I also noticed, that the widget wohnt show something either..
Is this a known issue? I could not find something similar to this in the release notes.
I also submitted this bug in the feedback app.
So I have been using the iOS 18 beta and I would like to say first and foremost really great update I love the timed messages and the car Sickness stuff that’s awesome but my only problem with the update is screen time. I have screen time on my phone and when I updated to iOS 18 beta I can’t seem to claim more screen time. I have my screen time to where I can ignore it once I run out But in the new update I can seem press the button all I want but It wont give me more screen time. This Is what I imagine a minor fix and I would really appreciate if this was fixed soon. But other than that small detail Amazing update love what your doing over here at apple!