Tl:dr What are some reasons my bundleIDs aren't showing up and does anyone have good resources to setup the screentime API/DeviceActivityMonitorExtension?
I'm working on an iOS app that uses the FamilyControls and DeviceActivity frameworks to monitor and restrict app usage. The app allows users to select apps and set usage limits. When a limit is reached, a DeviceActivityMonitorExtension should block the selected apps.
My App setup: Have a model that is called when users select apps to manage these app bundle IDs are then serialized and sent to the Device Monitor Extension via App Group so it can be used when the event threshold is reached. Cant use Application Tokens because they are not serielizable and cant be passed to the extension.
Problem: While testing, I’m unable to retrieve the bundleIdentifier and localizedDisplayName from the Application objects after selecting apps. Instead, these properties are nil or empty, preventing me from saving the bundle IDs to share with the extension via App Groups.
Assumptions: I suspect this issue is due to missing the com.apple.developer.screentime.api entitlement, which might be required to access these properties even during development. I've requested for the entitlement but its still under review.
Key Code Snippets:
Authorization Request:
class ScreenTimeManager: ObservableObject {
static let shared = ScreenTimeManager()
@Published var isAuthorized: Bool = false
func requestAuthorization() async {
do {
try await AuthorizationCenter.shared.requestAuthorization(for: .individual)
DispatchQueue.main.async {
self.isAuthorized = AuthorizationCenter.shared.authorizationStatus == .approved
print("Authorization status: \(AuthorizationCenter.shared.authorizationStatus)")
}
} catch {
DispatchQueue.main.async {
print("Authorization failed: \(error.localizedDescription)")
self.isAuthorized = false
}
}
}
}
Accessing bundleIdentifier:
print("addAppGroup() Called")
let managedApps = selection.applications.compactMap { application -> ManagedApp? in
guard let token = application.token else {
print("No token for application: \(application)")
return nil
}
let app = Application(token: token)
print("New Application instance: \(app)")
guard let bundleID = app.bundleIdentifier, !bundleID.isEmpty else {
print("Bundle identifier is empty or nil for application: \(app)")
return nil
}
let displayName = app.localizedName ?? "Unknown App"
print("Processing application with bundleIdentifier: '\(bundleID)' and displayName: '\(displayName)'")
return ManagedApp(
bundleIdentifier: bundleID,
applicationToken: token,
localizedDisplayName: displayName
)
}
if managedApps.isEmpty {
print("No managed apps created. Exiting addAppGroup().")
return
}
// Continue with creating DeviceActivityEvent...
}
Logs - Shows application token but never bundleID or LocalizedDisplayname
Application(bundleIdentifer: nil, token: Optional(128 byte <TOKEN_PRESENT>), localizedDisplayName: nil)
What I've Tried:
Ensured Screen Time is enabled on the device.
Verified App Group configuration in both app and extension.
Checked that authorization is being requested and the status is .approved.
Cleaned and rebuilt the project.
Questions:
Is the com.apple.developer.screentime.api entitlement required to access bundleIdentifier and localizedDisplayName when using .individual authorization?
Is there a way to access these properties without the entitlement, or am I missing a configuration step?
Has anyone faced a similar issue and found a solution?
Lastly, is there a good place for additional resources on the screentime API??