Hello,
I've been working with an app that leverages a DeviceActivityReport app extension. I want to ensure that the main app can gracefully handle scenarios where the connection to the app extension might get terminated unexpectedly.
Can anyone guide me on how to detect from the main app when the connection to the app extension gets terminated? I believe being able to detect this would allow for better error handling and potentially reduce instances where the UI appears blank due to a lost connection.
Thank you for any insights or advice on this topic.
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
Hello Apple Developer Community,
We're experiencing a critical issue with the Screen Time frameworks, and it's affecting one of our users severely. I'm hoping someone here can provide guidance or a potential solution.
Details:
Our app offers a feature using the ManagedSettings shield that lets users block all apps based on a set schedule.
After the scheduled block ends, the apps are expected to become accessible again.
In one case, a user reported that the apps did not unblock after the schedule ended.
Upon trying to manually end the session from within our app, the app only displays a blank white screen.
The user attempted to disable Screen Time access for our app via the iOS settings, but the apps remained blocked.
Even after completely disabling Screen Time from the settings or restarting the phone, the apps stayed blocked.
Interestingly, I attempted to replicate the issue on my end by toggling Screen Time settings and restarting, but everything worked as expected and I could not reproduce the problem.
This issue, though seemingly isolated, has rendered a user's phone virtually unusable, and highlights a potential high-impact bug within the Screen Time framework. It feels necessary for there to be a "master off-switch" or a fail-safe mechanism in these scenarios.
Any insights, solutions, or workarounds would be deeply appreciated. It's crucial for us to support our user and resolve this promptly.
Thank you in advance!
Topic:
App & System Services
SubTopic:
General
Tags:
Managed Settings
Family Controls
Device Activity
I'm encountering a problem with the DeviceActivityMonitor framework on iOS 17 that wasn't present in iOS 16. The app extension sends analytics events via the Segment SDK whenever the extension's functions are called. This setup worked flawlessly on iOS 16. However, since upgrading to iOS 17, it appears that the vast majority of my iOS 17 users are not triggering the expected analytics events.
I'm aware that network requests in app extensions are not officially supported, yet somehow, Segment's SDK managed to function without issues in the previous OS version. Could there have been any changes in iOS 17 related to app extensions or the DeviceActivityMonitor framework that might be influencing this change in analytics behavior? Or perhaps there's a new restriction or modification in the app extension's network capabilities that I might be overlooking?
Any insights into these changes or guidance on how to ensure analytics events are triggered reliably within the app extension on iOS 17 would be greatly appreciated.
Thank you in advance for your help!
My app uses DeviceActivitySchedule to let users set schedules to block certain apps. I naturally want to understand how my users are using the feature, so I capture analytics events using Segment.
Ever since the release of iOS 17.1, analytics events from DeviceActivityMonitor have stopped firing. I believe this is due to the fact that the app extension that DeviceActivityMonitor runs in does not support asynchronous network requests. (However, I'm not sure why the analytics were working correctly with iOS 16).
What is the best way to capture analytics inside the DeviceActivityMonitor app extension in iOS 17?
Topic:
App & System Services
SubTopic:
General
Tags:
Extensions
Managed Settings
Family Controls
Device Activity
I use App Groups to share UserDefaults data between my host app and DeviceActivityMonitor extension.
On iOS 17, it appears that reading @AppStorage variables are causing my DeviceActivityMonitor extension callback functions to crash. Weirdly, writing values is okay.
I see this in the extension logs:
Couldn't read values in CFPrefsPlistSource<0x10fe251d0> (Domain: GROUP_NAME, User: kCFPreferencesAnyUser, ByHost: Yes, Container: (null), Contents Need Refresh: Yes): Using kCFPreferencesAnyUser with a container is only allowed for System Containers, detaching from cfprefsd
However, through searching this log message on the internet and the fact that it also appears in my host app logs without crashing, this seems to be a warning - possibly indicating an issue but also a possible red herring.
But the fact remains that when I don't read UserDefaults values or variables decorated with @AppStorage in the DeviceActivityMonitor extension, everything works fine.
Are UserDefaults, and specifically @AppStorage decorators supported in the DeviceActivityMonitor extension?
Topic:
App & System Services
SubTopic:
Core OS
Tags:
iOS
Extensions
Managed Settings
Device Activity
Our app uses DeviceActivityReport to display the user’s screen time. The performance of DeviceActivityReport is often very poor. These issue occur commonly:
Screen time is reported as 0 minutes
DeviceActivityReport View appears completely blank
The host app loses connection with the DeviceActivityReport altogether
I have implemented several workarounds which only slightly improve the performance, to varying degrees depending on the device iOS:
Inside the DeviceActivityReport code - retry fetching screen time data until it returns a non-zero result
Implement a “refresh” button which reloads the DeviceActivityReport view from the host app
However, due to the sandboxed nature of DeviceActivityReport, there is no way for the host application to tell if the DeviceActivityReport extension is experiencing these performance issues. It results in a really bad user experience.
I am building the app with Xcode 14 due to another issue where DeviceActivityReport fails to load for all iOS 16 devices when built with Xcode 15 (this is a know issue, here’s a link to a discussion on the developer forums: https://developer.apple.com/forums/thread/735915). However, when testing on iOS 17 devices with Xcode 15 builds, the above issues still occur.
I have received no crash reports from DeviceActivityReport.
These issues are known bugs and have been discussed on the developer forums, but I haven't yet seen a solution. Other screen time apps exist that use the DeviceActivityReport seemingly flawlessly, so I know that there is a way to improve the performance of DeviceActivityReport in my app.
Please help! I have been dealing with this poor performance for a long time now with almost no improvement!
I am developing an app for iOS 16 using the Xcode 14.0 beta. I've created certificates and provisioning files both through Xcode and manually following instructions at https://developer.apple.com/documentation/xcode/running-your-app-in-the-simulator-or-on-a-device, but every time when trying to install the app on my iPhone 13 Pro Max running iOS 16.0 beta, I get the error The code signature version is no longer supported. Googling around, I haven't found anything funky about code signing with iOS 16 beta, but that might be because it is so new. Is there any reason that my code signature would be invalid given my developer setup? It's attached to my Apple ID and I am a member of the Apple Developer Program. Here's the details to my error if you want to dig in:
Details
Unable to install "Screentox"
Domain: com.apple.dt.MobileDeviceErrorDomain
Code: -402620375
User Info: {
DVTErrorCreationDateKey = "2022-08-02 13:43:50 +0000";
IDERunOperationFailingWorker = IDEInstalliPhoneLauncher;
}
--
The code signature version is no longer supported.
Domain: com.apple.dt.MobileDeviceErrorDomain
Code: -402620375
User Info: {
DVTRadarComponentKey = 487925;
MobileDeviceErrorCode = "(0xE8008029)";
"com.apple.dtdevicekit.stacktrace" = (
0 DTDeviceKitBase 0x0000000122538c30 DTDKCreateNSErrorFromAMDErrorCode + 235
1 DTDeviceKitBase 0x00000001225752ff __90-[DTDKMobileDeviceToken installApplicationBundleAtPath:withOptions:andError:withCallback:]_block_invoke + 155
2 DVTFoundation 0x000000010b7453b5 DVTInvokeWithStrongOwnership + 71
3 DTDeviceKitBase 0x0000000122575027 -[DTDKMobileDeviceToken installApplicationBundleAtPath:withOptions:andError:withCallback:] + 1409
4 IDEiOSSupportCore 0x0000000121f6c66c __118-[DVTiOSDevice(DVTiPhoneApplicationInstallation) processAppInstallSet:appUninstallSet:installOptions:completionBlock:]_block_invoke.301 + 3520
5 DVTFoundation 0x000000010b87a629 __DVT_CALLING_CLIENT_BLOCK__ + 7
6 DVTFoundation 0x000000010b87b13d __DVTDispatchAsync_block_invoke + 196
7 libdispatch.dylib 0x00007ff81d8990cc _dispatch_call_block_and_release + 12
8 libdispatch.dylib 0x00007ff81d89a317 _dispatch_client_callout + 8
9 libdispatch.dylib 0x00007ff81d8a0317 _dispatch_lane_serial_drain + 672
10 libdispatch.dylib 0x00007ff81d8a0dfd _dispatch_lane_invoke + 366
11 libdispatch.dylib 0x00007ff81d8aaeee _dispatch_workloop_worker_thread + 753
12 libsystem_pthread.dylib 0x00007ff81da4dfd0 _pthread_wqthread + 326
13 libsystem_pthread.dylib 0x00007ff81da4cf57 start_wqthread + 15
);
}
--
Analytics Event: com.apple.dt.IDERunOperationWorkerFinished : {
"device_model" = "iPhone14,3";
"device_osBuild" = "16.0 (20A5328h)";
"device_platform" = "com.apple.platform.iphoneos";
"launchSession_schemeCommand" = Run;
"launchSession_state" = 1;
"launchSession_targetArch" = arm64;
"operation_duration_ms" = 4934;
"operation_errorCode" = "-402620375";
"operation_errorDomain" = "com.apple.dt.MobileDeviceErrorDomain";
"operation_errorWorker" = IDEInstalliPhoneLauncher;
"operation_name" = IDEiPhoneRunOperationWorkerGroup;
"param_consoleMode" = 0;
"param_debugger_attachToExtensions" = 0;
"param_debugger_attachToXPC" = 1;
"param_debugger_type" = 5;
"param_destination_isProxy" = 0;
"param_destination_platform" = "com.apple.platform.iphoneos";
"param_diag_MainThreadChecker_stopOnIssue" = 0;
"param_diag_MallocStackLogging_enableDuringAttach" = 0;
"param_diag_MallocStackLogging_enableForXPC" = 1;
"param_diag_allowLocationSimulation" = 1;
"param_diag_gpu_frameCapture_enable" = 0;
"param_diag_gpu_shaderValidation_enable" = 0;
"param_diag_gpu_validation_enable" = 0;
"param_diag_memoryGraphOnResourceException" = 0;
"param_diag_queueDebugging_enable" = 1;
"param_diag_runtimeProfile_generate" = 0;
"param_diag_sanitizer_asan_enable" = 0;
"param_diag_sanitizer_tsan_enable" = 0;
"param_diag_sanitizer_tsan_stopOnIssue" = 0;
"param_diag_sanitizer_ubsan_stopOnIssue" = 0;
"param_diag_showNonLocalizedStrings" = 0;
"param_diag_viewDebugging_enabled" = 1;
"param_diag_viewDebugging_insertDylibOnLaunch" = 1;
"param_install_style" = 0;
"param_launcher_UID" = 2;
"param_launcher_allowDeviceSensorReplayData" = 0;
"param_launcher_kind" = 0;
"param_launcher_style" = 0;
"param_launcher_substyle" = 0;
"param_runnable_appExtensionHostRunMode" = 0;
"param_runnable_productType" = "com.apple.product-type.application";
"param_runnable_type" = 2;
"param_testing_launchedForTesting" = 0;
"param_testing_suppressSimulatorApp" = 0;
"param_testing_usingCLI" = 0;
"sdk_canonicalName" = "iphoneos16.0";
"sdk_osVersion" = "16.0";
"sdk_variant" = iphoneos;
}
--
System Information
macOS Version 12.4 (Build 21F79)
Xcode 14.0 (21304.3) (Build 14A5270f)
Timestamp: 2022-08-02T09:43:50-04:00
Within the DeviceActivity API, the documentation for DeviceActivityCenter.startMonitoring says: "Attempting to monitor too many activities or activities that are too tightly scheduled can cause this method to throw an error."
Is there a documented limit of the amount of activities that are able to be monitored simultaneously? I understand that monitoring "too many activities" will throw an excessiveActivities error, but I can not find documentation that specifically identifies the conditions that this error can be thrown.
DeviceActivityReport view often shows up blank in the host app. What's the best way to refresh the view when this occurs?
The DeviceActivityReport is often laggy or sometimes doesn't show up at all. Quitting and re-opening the app usually fixes this problem.
I'm wondering, is there a way to programmatically terminate and then re-launch the DeviceActivityReport App Extension from the host app? This way, that could act as a "refresh" when the DeviceActivityReport fails to show up.
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?
I created a ShieldConfigurationExtension in Xcode 14.3 with File > New > Target > ShieldConfigurationExtension. This created the extension with all the necessary Info.plist values (correct NSExtensionPrincipalClass, etc.), with the extension included in embedded content in the host app target.
No matter what I try, the extension is not getting invoked when I shield applications from my host app. The custom UI does not show as the shield, and looking at the debugger, an extension process is never invoked.
I am shielding categories like this:
let managedSettings = ManagedSettingsStore()
...
managedSettings.shield.applicationCategories = .all()
And my extension code overrides all the ShieldConfigurationDataSource functions.
class ShieldConfigurationExtension: ShieldConfigurationDataSource {
override func configuration(shielding application: Application) -> ShieldConfiguration {
return ShieldConfiguration(
backgroundBlurStyle: UIBlurEffect.Style.systemThickMaterial,
backgroundColor: UIColor.white,
icon: UIImage(systemName: "stopwatch"),
title: ShieldConfiguration.Label(text: "You are in a Present Session", color: .yellow)
)
}
override func configuration(shielding application: Application, in category: ActivityCategory) -> ShieldConfiguration {
return ShieldConfiguration(
backgroundBlurStyle: UIBlurEffect.Style.systemThickMaterial,
backgroundColor: UIColor.white,
icon: UIImage(systemName: "stopwatch"),
title: ShieldConfiguration.Label(text: "You are in a Present Session", color: .yellow)
)
}
override func configuration(shielding webDomain: WebDomain) -> ShieldConfiguration {
return ShieldConfiguration(
backgroundBlurStyle: UIBlurEffect.Style.systemThickMaterial,
backgroundColor: UIColor.white,
icon: UIImage(systemName: "stopwatch"),
title: ShieldConfiguration.Label(text: "You are in a Present Session", color: .yellow)
)
}
override func configuration(shielding webDomain: WebDomain, in category: ActivityCategory) -> ShieldConfiguration {
return ShieldConfiguration(
backgroundBlurStyle: UIBlurEffect.Style.systemThickMaterial,
backgroundColor: UIColor.white,
icon: UIImage(systemName: "stopwatch"),
title: ShieldConfiguration.Label(text: "You are in a Present Session", color: .yellow)
)
}
}
What am I missing?
Topic:
App & System Services
SubTopic:
General
Tags:
Extensions
Managed Settings
Family Controls
Device Activity
There have been several posts (i.e. here, here) about the lagginess of the DeviceActivityReport extension. Often it takes a few seconds for the view to load, or sometimes doesn't show up at all.
I've confirmed this is not a case of excessive memory usage in the extension (exceeding 100MB), because I've profiled the extension and it consistently maxes out at 10MB.
I've placed a loading screen behind the DeviceActivityReport inside a ZStack in the host app in order to see if the lag is because it takes some time for the extension to spin up - but the loading screen does not appear, indicating that the extension is running right away, but receiving the view from the extension in the host app is where the lag happens.
It's been extremely difficult to debug because the lag only occurs a fraction of the time, and DeviceActivityReport is pretty much a black box. There's no documentation about how the host app and extension actually communicate. I've also combed through the logs using the Console app on Mac with no indication of any issues, (but I do see the message "Connection to view service was invalidated" coming from the extension even when there is no lag).
I'm pretty convinced that the problem lies in the host app, because when I strip everything away from the host app, DeviceActivityReport never lags. I suspect that there are processes running (network requests, async tasks, or state updates) that block the report view from being received in the host app.
Could you please help me understand why this could be happening, with as many details as you could provide? Any details on how the host and extension communicate, what processes could block the view from appearing, or anything else. Seems like this is a common issue but plenty of apps also don't experience it. Any guidance you can provide would be extremely helpful, as I've been trying to fix this bug every since I've been working with this API with no luck. Thanks in advance!
Our app uses a 24-hour DeviceActivityMonitor repeating schedule to send users notifications for every hour of screen time they spend on their phone per day. Notifications are sent from eventDidReachThreshold callbacks at 1, 2, 3, etc, hour thresholds to keep them aware of their screen time.
We have recently received an influx of emails from our users that after updating to iOS 17.6.1 their DeviceActivityMonitor notifications are saying their screen time was much higher than what is shown in DeviceActivityReport and their device's Screen Time settings.
These users have disabled "Share Across Devices" - but I suspect the DeviceActivityMonitor is still getting screen time from their other devices even though that setting is turned off.
Has anybody else noticed this, understands what is causing this, or could recommend a fix that we can tell our users to do?
For my app, I use the DeviceActivity API to define a daily, repeating DeviceActivitySchedule that begins at 12:00AM and ends at 11:59 PM every day. I notice that when the device is powered off before 11:59 PM and powered back on the next day, neither the intervalDidEnd nor intervalDidStart callback functions are called. It appears that the interval extends into the next day and only ends once 11:59 PM comes around again.
What is the expected behavior of the system to call the intervalDidStart and intervalDidEnd callback functions when the device is powered off during the scheduled start or end time?
Topic:
App & System Services
SubTopic:
General
Tags:
Managed Settings
Family Controls
Device Activity
Screen Time