I think I have found a bug in the Apple "Screen Time" API.
I have filed it via a Feedback Assistant, but I can see that some apps have somehow found a workaround to this issue — so wondering how they did it.
The issue:
Create a simple two tabs view:
TabView {
Tab1View()
.tabItem {
Label("Tab 1", systemImage: "1.circle.fill")
}
Tab2View()
.tabItem {
Label("Tab 2", systemImage: "2.circle.fill")
}
}
Each tab has a different "Screen Time" report, e.g.
struct Tab2View: View {
var body: some View {
DeviceActivityReport(Utils.weeklyContext, filter: Utils.filterWeekly)
}
}
When you switch the tabs quickly, the "Screen Time" process crashes, leaving both reports blank.
The size of the "DeviceReportActivity" remains the same (it's just blank), so there is no way to tell if it crashed. Also, there is no way to know that the "Screen Time" process has crashed. This leaves the app in an unusable state.
Here is a video illustrating the issue:
https://www.youtube.com/watch?v=WrRpohf9tmw&ab_channel=MarcinCzech
The code is here:
https://github.com/AndroidGecko/Screen-Time/tree/screen_time_issues
However, apps like Jomo or Opal have tabs with two "Screen Time" reports.
And if you switch tabs quickly, you can see it breaking, but somehow they make it re-appear. I know I can re-fresh the view using .id() on the report, but I cannot see a way of detecting when the report crashes. Forcing a new .id on each tab switch is not the right solution as it re-fetches the whole report (Jomo and Opal don't do it).
Question:
How can I detect that a "Screen Time" process has crashed? (to create a workaround for that issue). Or maybe there is another way to approach this issue?
Thank you 🙏
Post
Replies
Boosts
Views
Activity
Hey 👋
I have an extension of type "Device Activity Report Extension".
Is there a way to know from the parent app if the extension process is alive?
the process name is DeviceActivityReportService
Why would I like to detect that?
The extension sometimes crashes due to memory pressure and I would like to reload the view automatically when this happens.
This issue happens under normal app use — the user switches quickly between two tabs that have DeviceActivityReport.
I filed a bug for this with a sample project to replicate (12192929)
Here is an output from the Console app when the DeviceActivityReportService is killed and the UI disappears:
kernel memorystatus: killing process 33061 [DeviceActivityReportService] in high band FOREGROUND (100) - memorystatus_available_pages: 68660
kernel DeviceActivityReportService[33061] Corpse allowed 1 of 5
SpringBoard [xpcservice<com.apple.DeviceActivityUI.DeviceActivityReportService([application<com.labalab.Screen-Time.marcin>:33046])>:33061] Workspace connection invalidated.
SpringBoard [xpcservice<com.apple.DeviceActivityUI.DeviceActivityReportService([application<com.labalab.Screen-Time.marcin>:33046])>:33061] Now flagged as pending exit for reason: workspace client connection invalidated
SpringBoard [FBInterfaceOrientationServiceServer] Removing client xpcservice<com.apple.DeviceActivityUI.DeviceActivityReportService([application<com.labalab.Screen-Time.marcin>:33046])>:33061.
SpringBoard Removed client for observing orientation events: <FBServiceFacilityServerClientHandle: 0x281fa23a0; com.apple.frontboardservices.orientation-observer; xpcservice<com.apple.DeviceActivityUI.DeviceActivityReportService([application<com.labalab.Screen-Time.marcin>:33046])>:33061: remote>
kernel 266908.072 memorystatus: killing_specific_process pid 33061 [DeviceActivityReportService] (per-process-limit 100) 35873KB - memorystatus_available_pages: 68793
Screen Time Terminating interface and invalidating assertion: identifier: com.apple.DeviceActivityUI.DeviceActivityReportService; assertion: 0x282316b70
Screen Time Terminating interface and invalidating connection: identifier: com.apple.DeviceActivityUI.DeviceActivityReportService; assertion: 0x0