Device Activity

RSS for tag

Monitor web and app usage through custom time windows and events.

Posts under Device Activity tag

86 Posts
Sort by:

Post

Replies

Boosts

Views

Activity

Provisioning Profile Error
I'm building an app that uses the Screen Time API and DeviceActivityMonitoring Framework. It works when I run the simulator build on iPhone 16 but when I try to launch it on my own iPhone, I get these errors. Provisioning profile "iOS Team Provisioning Profile: Kanso- Digital-Wellness.Kanso-v2" doesn't include the com.apple.developer.device-activity.monitoring entitlement. KansoMonitorExtension 1 issue x Provisioning profile "iOS Team Provisioning Profile: Kanso-Digital-Wellness.Kanso-v2.KansoMonitorExtension" doesn't include the com.apple.developer.device-activity.monitoring en... Read something online that said a reboot would fix this, but I tried and no luck. Any ideas? I'm not very technical, so would pay someone to fix this for me :)
0
0
127
5d
Problem with DeviceActivitySchedule and DeviceActivityMonitor
Hey, I’m having some issues with DeviceActivitySchedule and DeviceActivityMonitor. I want to create a schedule that blocks apps (by family control) when it starts. However, even when the schedule is supposed to start on this iPhone, nothing happens, and no logs are being recorded main target: // TestView_.swift // Sloth // // Created by on 11/01/2025. // import SwiftUI import DeviceActivity import FamilyControls import ManagedSettings struct TestView_: View { var body: some View { VStack(spacing: 20) { Text("Test DeviceActivityMonitor") .font(.title) Button("Start test mon") { let now = Date() let start = Calendar.current.date(byAdding: .minute, value: 2, to: now)! let end = Calendar.current.date(byAdding: .minute, value: 20, to: now)! print("thd") DeviceScheduleTester().scheduleTestActivity(startDate: start, endDate: end) } } .padding() } } extension DeviceActivityName { static let daily = DeviceActivityName("daily") } DeviceActivityMonitor: class DeviceScheduleTester { private let center = DeviceActivityCenter() func scheduleTestActivity(startDate: Date, endDate: Date) { let calendar = Calendar.current let startComponents = calendar.dateComponents([.hour, .minute], from: startDate) let endComponents = calendar.dateComponents([.hour, .minute], from: endDate) // Tworzymy schedule let schedule = DeviceActivitySchedule( intervalStart: startComponents, intervalEnd: endComponents, repeats: true ) do { try center.startMonitoring(.daily, during:schedule) print("startMonit /(\(schedule))") } catch { print("ghfgh") } } } struct TestView__Previews: PreviewProvider { static var previews: some View { TestView_() } } DeviceActivityMonitor target: // BlockingAppsMonitorExtension // // Created by on 10/01/2025. import DeviceActivity import FamilyControls import ManagedSettings import os let logger = Logger() public class BlockingAppsMonitor: DeviceActivityMonitor { private let store = ManagedSettingsStore() public override func intervalDidStart(for activity: DeviceActivityName) { super.intervalDidStart(for: activity) print("Rozpoczęcie interwału blokowania \(activity.rawValue)") logger.info("intervalDidStart") startBlocking() } public override func intervalDidEnd(for activity: DeviceActivityName) { super.intervalDidEnd(for: activity) print("Zakończenie interwału blokowania \(activity.rawValue)") logger.info("intervalDidend") stopBlocking() } @discardableResult private func startBlocking() -> Int { print("number of unique apps") return 51 store.shield.applicationCategories = .all() // return exceptions.count } private func stopBlocking() { store.shield.applicationCategories = nil store.shield.applications = nil } } INB4: In both files are added family controls Secent file is added in DeviceActivityMonitor target. Apple answer please?
1
0
159
8h
DeviceActivityReportExtension / ScreenTimeBriefReport does not localize strings
Hello, In one of our apps we use DeviceActivityReportExtension to show the user how much screen time is remaining. The calculation is working as expected, but we have noticed that the labels in our ScreenTimeBriefReport are not localized to the device language. Example: Device with language set to Swedish App fully translated to English and Swedish Result: All labels in app are using the Swedish translations, except the strings in our ScreenTimeBriefReport instance. These labels are using the English localization. I've verified it's using the English localization from our Localizable.xcstrings file. I tried logging device language from our ScreenTimeBriefReport instance, but I could not see anything in Console.app. I guess this is intentional so no sensitive user information can be extracted. Is this a known feature or bug? If it's the latter, is there a known workaround? Sincerely, César
1
0
162
1w
Screen-time in Device Activity Report Extension vs In Phone Settings
Am showing daily screen-time of a user in my app in Device Activity Report Extension. The only way to get that is to sum up all the activityDuration of apps/categories/domains. But it differs a lot from phone's settings screen-time, why? I have debugged in details and counted manually the time spent on each app and it turned out that the calculation is appearing correctly in my app but Phone settings showing quite less time on top (Day).
0
0
121
2w
Possible to access CoreData/Persistent storage from DeviceActivityReportExtension?
This is more a general question of whether it is possible to share persistent/coredata from the main app to Screentime-related extensions such as DeviceActivityReportExtension. I've set my code up (e.g., App Groups, files to different targets, using nspersistentcontainer with app group url, etc.) in a way that it builds, and the extension seems to recognize my CoreData schema (able to query using fetchrequest). But the data returned is always null. So i'm wondering if it is even possible to READ app data from the extension. I understand it is not possible to write or pass data from the extension back to the app. I've also been able to read data that was saved in main app from UserDefaults in my extension.
0
0
166
3w
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!
0
1
162
Dec ’24
How to Filter App Usage for a Specific Time Period Using Screen Time API?
I am working on a SwiftUI app using the Screen Time API and the DeviceActivityReport view to display app usage data. My current implementation successfully shows daily app usage using a DeviceActivityFilter with the .daily(during:) segment. However, I need to filter this data to show app usage only for a specific time period during the day, e.g., 4:00 PM to 5:00 PM. I created a DeviceActivityFilter with a .daily(during:) segment and passed a DateInterval for the desired time range: let now = Date() let startTime = calendar.date(bySettingHour: 16, minute: 0, second: 0, of: now)! let endTime = calendar.date(bySettingHour: 17, minute: 0, second: 0, of: now)! let timeInterval = DateInterval(start: startTime, end: endTime) let filter = DeviceActivityFilter( segment: .daily(during: timeInterval), users: .all, devices: .init([.iPhone]) ) I applied this filter to the DeviceActivityReport view: DeviceActivityReport(context, filter: filter) Even with the DateInterval set for the specific time range, the report still shows the total daily usage for each app, instead of restricting the results to the specified 1:00 PM to 5:00 PM range.
0
0
163
Dec ’24
Screen Time API / Device Activity
Hello I am wondering how and if it even is possible to grab the amount of times a user has opened a specific app. Of course these apps will be selected for tracking by the user through the FamilyControls API, but is it possible to then list those selected apps and their amount of openings? I know Screen Time API is very strict with giving developers control of this information outside of just displaying a view so I don't know if this is possible. I saw that DeviceActivityData.ApplicationActivity has a value called "numberOfPickups" but I'm not sure how to access that value and display it in my app. Thank you
1
0
285
Dec ’24
Screen Time API
Hi everyone, I've been going through the forums and documentation, but I'm still unsure about how the Screen Time API works or whether it can achieve what I have in mind. Specifically, I want to display the current screen time value on a widget. Additionally, I’d like to use that screen time value for some calculations and represent the results in a different way within the widget. I’d really appreciate any guidance or insights. Thanks in advance! 😊
1
0
234
Dec ’24
DeviceActivityMonitor - Callbacks not trigger
Bellow I created Manager to be easier for me to handle app limits, but for some reason It never reached callbacks function, I have permission for screen time, I added the capabilities for it also, I'm sure, I send correctly the appTokens, categoriesTokens ... and the time limit and it also reach ✅ Monitoring started for..., I don't know what to do anymore: import SwiftUI import DeviceActivity import FamilyControls import ManagedSettings @MainActor class AppUsageManager: DeviceActivityMonitor, ObservableObject { static let shared = AppUsageManager() private let deviceActivityCenter = DeviceActivityCenter() private var monitoringSelections: [DeviceActivityName: (selection: FamilyActivitySelection, timeLimit: DateComponents)] = [:] private var resetTimer: Timer? private override init() { super.init() print("🟢 AppUsageManager initialized.") } // MARK: - Public Methods /// Configures monitoring for a selection with a specific event name and time limit. func configureMonitoring( for selection: FamilyActivitySelection, timeLimitInMinutes: Int, activityName: String, eventName: String ) { let activityName = DeviceActivityName(activityName) let eventName = DeviceActivityEvent.Name(eventName) monitoringSelections[activityName] = (selection, DateComponents(minute: timeLimitInMinutes)) setupMonitoring(for: activityName, with: eventName) } /// Stops monitoring for a specific event. func stopMonitoring(for activityName: String) { let activityName = DeviceActivityName(activityName) Task { print("🛑 Stopping monitoring for \(activityName.rawValue).") deviceActivityCenter.stopMonitoring([activityName]) monitoringSelections.removeValue(forKey: activityName) } } /// Stops all monitoring. func stopAllMonitoring() { print("🛑 Stopping monitoring") deviceActivityCenter.stopMonitoring() } // MARK: - Private Methods /// Sets up monitoring for a specific event. private func setupMonitoring( for activityName: DeviceActivityName, with eventName: DeviceActivityEvent.Name ) { stopAllMonitoring() guard let (selection, timeLimit) = monitoringSelections[activityName] else { print("⚠️ No selection configured for \(activityName.rawValue).") return } print("🛠 Setting up monitoring for \(activityName.rawValue).") print("📋 Monitoring Details:") print("- Time Limit: \(timeLimit.minute ?? 0) minutes.") let warningThreshold = DateComponents(minute: 3) let timeZone = TimeZone.current let schedule = DeviceActivitySchedule( intervalStart: DateComponents(timeZone: timeZone, hour: 0, minute: 0, second: 0), intervalEnd: DateComponents(timeZone: timeZone, hour: 23, minute: 59, second: 59), repeats: true, warningTime: warningThreshold ) let events: [DeviceActivityEvent.Name: DeviceActivityEvent] = [ eventName: DeviceActivityEvent( applications: selection.applicationTokens, categories: selection.categoryTokens, webDomains: selection.webDomainTokens, threshold: timeLimit ) ] do { try deviceActivityCenter.startMonitoring( activityName, during: schedule, events: events ) print("✅ Monitoring started for \(activityName.rawValue) with time limit \(timeLimit.minute ?? 0) minutes.") } catch { print("❌ Failed to start monitoring \(activityName.rawValue): \(error.localizedDescription)") } } // MARK: - DeviceActivityMonitor Overrides override func intervalDidStart(for activity: DeviceActivityName) { print("🟢 Interval for \(activity.rawValue) started.") } override func intervalWillStartWarning(for activity: DeviceActivityName) { print("⚠️ Warning: \(activity.rawValue) is about to start.") } /// Handles warnings for approaching the time limit. override func eventWillReachThresholdWarning( _ event: DeviceActivityEvent.Name, activity: DeviceActivityName ) { super.eventWillReachThresholdWarning(event, activity: activity) print("⚠️ Warning: \(activity.rawValue) is about to reach its time limit.") print("⚠️ Event: \(event.rawValue)") } /// Handles when the time limit is reached. override func eventDidReachThreshold( _ event: DeviceActivityEvent.Name, activity: DeviceActivityName ) { super.eventDidReachThreshold(event, activity: activity) print("🟢 Limit reached.") Task { @MainActor in print("🕒 \(activity.rawValue) has reached its time limit.") print("🕒 Event: \(event.rawValue)") guard let (selection, _) = monitoringSelections[activity] else { print("⚠️ No selection configured for \(activity.rawValue).") return } blockApps(for: selection) } } // MARK: - Blocking Logic /// Blocks the selected apps/categories. private func blockApps(for selection: FamilyActivitySelection) { print("🔒 Blocking apps/categories for selection.") print("- Applications: \(selection.applicationTokens)") print("- Categories: \(selection.categoryTokens)") let store = ManagedSettingsStore() store.shield.applications = selection.applicationTokens store.shield.applicationCategories = .specific(selection.categoryTokens) print("🔒 Apps/categories blocked successfully.") } }
1
1
230
Dec ’24
Screen Time API ( screen to select app)
Hello, we are building an app to limit children's screen time and using Screen Time API. We found bug on the screen where the user selects app category and apps, if the user selects Other category, the screen will crash (he will be empty, but if you reload screen, it will show apps again as usual). We hope that Apple will fix it someday, but we are trying to notify our users about this problem, and the problem is that we don't know what the user selects on Apple screen with apps till the user clicks Save or Done. But we need to notify him either when he clicks on the Other category or when he faces crash of this screen. We want to show a pop-up to user with explanation why screen crashed.
2
0
283
Dec ’24
DeviceActivityCenter.startMonitoring occasionally crash in the morning
When I use the screen time API, the app occasionally crashes in the morning. I mean the UI freeze lasts for more than ten seconds. But the weird thing is that I work normally during the day, that is, in the morning, when I just woke up. (There is no Do Not Disturb mode). This problem has been bothering me for several days, please help. The specific crash log is as follows, and the specific code is as follows. Model: iPhone 15 Pro, iOS: 18.1.1 Thanks for your help! Code: private func startAppMonitoring(application: ApplicationToken, seconds: Int, isFromNow: Bool) { let schedule = DeviceActivitySchedule( intervalStart: isFromNow ? Calendar.current.dateComponents([.hour, .minute, .second], from: Date()) : DateComponents(timeZone: TimeZone(identifier:TimeZone.current.identifier), hour: 0, minute: 0, second: 0), intervalEnd: DateComponents(timeZone: TimeZone(identifier:TimeZone.current.identifier), hour: 23, minute: 58, second: 59), repeats: true, warningTime: DateComponents(minute: 1) ) let event = DeviceActivityEvent( applications: Set([application]), threshold: DateComponents(second: seconds) ) let center = DeviceActivityCenter() do { try center.startMonitoring(DeviceActivityName("\(application.hashValue)Usage"), during: schedule, events: [DeviceActivityEvent.Name("\(application.hashValue)Event"): event]) } catch { print("Error starting monitoring schedule: \(error)") } } Crash report:
2
0
279
Dec ’24
Device Activity Report Per hour Screen-time of apps for Graph
Hi everyone, I need to display a Graph based on Screen-time of apps per hour, from 12Am to 11PM. Am able to get the screen-time data for whole day with each app's total screen-time value. Am kind of confused how can I get the per hour screen-time of apps. I have applied filter of day DeviceActivityFilter( segment: .daily( during: Calendar.current.dateInterval( of: .day, for: .now )! ), users: .all, devices: .init([.iPhone, .iPad]) ) Am also using this data to display apps with their usage just like Apple's Screen_time in settings. I need to display exact same graph just like Apple's screen in phone settings for a Day.
1
0
253
Nov ’24
How to Share and Access Dynamically Updating Data Across Different Targets?
I have a app with two targets: a main DeviceActivityApp target and a DeviceReport target. In the DeviceReport target, I have a TotalActivityReport struct conforming to DeviceActivityReportScene. Inside its makeConfiguration method, I update a dynamically generated list of AppReport items. The list updates correctly in the DeviceReport target. // Define which context your scene will represent. let context: DeviceActivityReport.Context = .totalActivity // Define the custom configuration and the resulting view for this report. let content: (MonitorDeviceReport) -> TotalActivityViewFirst @ObservedObject var activityData:ActivityData func makeConfiguration(representing data: DeviceActivityResults<DeviceActivityData>) async -> MonitorDeviceReport { // Reformat the data into a configuration that can be used to create // the report's view. var appList:[AppsReport]=[] let totalActivityDuration = await data.flatMap { $0.activitySegments }.reduce(0, { $0 + $1.totalActivityDuration }) for await _data in data{ for await activity in _data.activitySegments{ for await category in activity.categories{ for await app in category.applications{ let name=app.application.localizedDisplayName ?? "No Name" let bundleId=app.application.bundleIdentifier ?? "nil" let duration=app.totalActivityDuration let appIcon=app.application.token let app=AppsReport(id:bundleId,duration:duration, name:name, icon:appIcon) appList.append(app) } } } } DispatchQueue.main.async { activityData.list=appList } return MonitorDeviceReport(duration:totalActivityDuration, apps:appList) } } public class ActivityData:ObservableObject{ @Published var list:[AppsReport]=[] public static let shared = ActivityData() }. // This is in MonitorReport target However, I need to access this dynamic list in my MyApp target, specifically in ContentView.swift. I tried using an ObservableObject (ActivityData) to share the data between targets, but the list always appears empty in the MyApp target. Here’s what I’ve tried so far: Created a shared ActivityData instance using @Published Passed the ActivityData instance to TotalActivityReport Used dependency injection and a singleton pattern for ActivityData Verified that makeConfiguration updates the list correctly in DeviceReport What could I be missing? How can I correctly share and access this data across targets?
0
0
225
Nov ’24
Device activity report data View is hidding when change the tab
I am working on the device activity report. and fetched data is loading on the chart. I am developing app using TabbarController. when I go to another tab and come back to the chart screen, it disappears. Here, I am working on a storyboard using Swift language, and device activity reports can be fetched only with SwiftUI. So, the problem is with it? Following the current code. @State private var context: DeviceActivityReport.Context = .init(rawValue: "Daily Activity") @State private var report: DeviceActivityReport? @State private var filter = DeviceActivityFilter( segment: .daily( during: Calendar.current.dateInterval( of: .day, for: .now )! ) // users: .all // devices: .init([.iPhone, .iPad]) ) @State var isReload: Bool = false var body: some View { ZStack { if isReload { LoadingView(title: "Data is loading...") } else if let report = report { report } else { DeviceActivityReport(context, filter: filter) } } .onAppear { DispatchQueue.main.async { report = DeviceActivityReport(context, filter: filter) } } } struct LoadingView: View { var title: String = "Please wait..." var body: some View { HStack { ProgressView(title) .font(.system(size: 14, weight: .medium)) .progressViewStyle(.horizontal) .tint(Color(.darkGray)) .padding(8) } .background(Color(.white)) .cornerRadius(8) .clipped() } }
0
0
303
Nov ’24