Family Controls

RSS for tag

Prevent access to the Screen Time API without guardian approval and provide opaque tokens that represent apps and websites.

Posts under Family Controls tag

186 Posts
Sort by:

Post

Replies

Boosts

Views

Activity

DeviceActivityMonitor Extension methods not being triggered at IOS16, but its work at IOS17
I'm writing an app that uses Family Control. Most of the functionality has already been debugged, including in the call try deviceActivityCenter.startMonitoring(activityName, during: schedule, events: [ eventName: event ]) Works fine on my IOS17 device, but on my old IOS16 device I found that it can't be called, like intervalDidStart, intervalDidEnd, eventDidReachThreshold etc can't be called. I checked some information, https://forums.developer.apple.com/forums/thread/724243 delete the Build Settings mentioned in this link, and change the ios Deployment Target to ios16, and found that it didn't work. Don't know where the problem is?
0
0
257
Feb ’24
Calling requestAuthorization() for a child account throws "restricted"?
I'm developing an iOS app that uses ScreenTime API. Locally, everything works as expected - I have two physical devices in one Apple Family, and calling AuthorizationCenter.shared.requestAuthorization(for: .child) on a child device shows standard authorization dialog. Currently the app is in a review by Apple, and they are saying they can't authorize as a child. From logs, and a screenshots provided by them, I see that on AuthorizationCenter.shared.requestAuthorization(for: .child) call, FamilyControlsError.restricted error is being thrown. I didn't encounter this error once during development and can't simulate this issue now either. Tried everything - authorization on account that is not a child, not in a family, tried restricting everything possible for a child's device from ScreenTime settings. This specific error is never triggered. Does anyone have idea why this error could happen? My last guess is the review team is using an enterprise account and that somehow intercepts with ScreenTime settings. But I don't have an enterprise account to test this theory.
4
1
851
Jul ’24
How to check app's Screen Time access?
Is there a way for me to programmatically check whether a user has disabled my app's access to Screen Time? I currently request Family Controls / Screen Time access upon download by calling the following: AuthorizationCenter.shared.requestAuthorization(for: .individual) I need to be able to detect, though, when a user has gone into Settings -> Screen Time and disabled my app's Screen Time access. I tried calling the following: AuthorizationCenter.shared.authorizationStatus But it appears to have a value of Approved even after I turn off my app's Screen Time access. Is there any way to accurately detect this in the code?
1
0
1k
Feb ’24
DeviceActivityMonitor Extension not working
I am developing a project with the Screen Time API, and I cannot understand why the methods inside DeviceActivityMonitor extension are not being called. Some points to note: I do start by requesting authorization from the User (this is working as expected when opening the app) Both the DeviceActivityMonitor Extension and the main app are under the same App Group I have added Family Controls capability to both targets and have the developer account to use it. I start by calling center.startMonitoring() I have overridden the original methods. Yet, when startMonitoring is called, there is no action that is supposed to be taken that is being taken, and as far as I can tell, the methods aren't even being called. Here are some relevant snippets of code: // EXT class DeviceActivityMonitorExtension: DeviceActivityMonitor { override func intervalDidStart(for activity: DeviceActivityName) { super.intervalDidStart(for: activity) let store = ManagedSettingsStore(named: .daily) } override func intervalDidEnd(for activity: DeviceActivityName) { super.intervalDidEnd(for: activity) let store = ManagedSettingsStore(named: .daily) store.clearAllSettings() } override func eventDidReachThreshold(_ event: DeviceActivityEvent.Name, activity: DeviceActivityName) { super.eventDidReachThreshold(event, activity: activity) let store = ManagedSettingsStore(named: .daily) let model = BeeFreeModel.shared let applications = model.selectionToDiscourage.applicationTokens let categories = model.selectionToDiscourage.categoryTokens let webDomains = model.selectionToDiscourage.webDomainTokens store.shield.applications = applications.isEmpty ? nil : applications store.shield.applicationCategories = categories.isEmpty ? nil : ShieldSettings.ActivityCategoryPolicy.specific(categories) store.shield.webDomains = webDomains.isEmpty ? nil : webDomains } } // APP extension DeviceActivityName { static let daily = Self("daily") } extension DeviceActivityEvent.Name { static let discouraged = Self("discouraged") } let schedule = DeviceActivitySchedule( intervalStart: DateComponents(hour: 0, minute: 0, second: 0), intervalEnd: DateComponents(hour: 23, minute: 59, second: 59), repeats: true ) class BeeFreeSchedule { static public func setSchedule() { print("Setting schedule...") print("Hour is: ", Calendar.current.dateComponents([.hour, .minute], from: Date()).hour!) let events: [DeviceActivityEvent.Name: DeviceActivityEvent] = [ .discouraged: DeviceActivityEvent( applications: BeeFreeModel.shared.selectionToDiscourage.applicationTokens, categories: BeeFreeModel.shared.selectionToDiscourage.categoryTokens, webDomains: BeeFreeModel.shared.selectionToDiscourage.webDomainTokens, threshold: BeeFreeModel.shared.thresholdToDiscourage ) ] let center = DeviceActivityCenter() do { print("Try to start monitoring...") // Call startMonitoring with the activity name, schedule, and events try center.startMonitoring(.daily, during: schedule, events: events) } catch { print("Error monitoring schedule: ", error) } } } // APP class BeeFreeModel: ObservableObject { // Import ManagedSettings to get access to the application shield restriction let store = ManagedSettingsStore() //@EnvironmentObject var store: ManagedSettingsStore @Published var selectionToDiscourage: FamilyActivitySelection @Published var thresholdToDiscourage: DateComponents @Published var setOfApps: [String] init() { selectionToDiscourage = FamilyActivitySelection() thresholdToDiscourage = DateComponents() var setOfAppIdentifiers: Set<String?> = Set<String?>() setOfApps = [String]() if selectionToDiscourage.applicationTokens.isEmpty {} else { for application in BeeFreeModel.shared.selectionToDiscourage.applications { setOfAppIdentifiers.insert(application.localizedDisplayName) setOfApps = setOfAppIdentifiers.compactMap { $0 }.sorted() } } } class var shared: BeeFreeModel { return _BeeFreeModel } func setSelection() { let applications = BeeFreeModel.shared.selectionToDiscourage } func changeThreshold(threshold: DateComponents) { thresholdToDiscourage = threshold } } // APP /// ... Button("Select Apps to Discourage") { isDiscouragedPresented = true } .familyActivityPicker(isPresented: $isDiscouragedPresented, selection: $model.selectionToDiscourage) } .onChange(of: model.selectionToDiscourage) { BeeFreeModel.shared.setSelection() } // ... // ... Button("Save Time") { saveTime() let new_threshold = DateComponents(hour: savedTime?.hours, minute: savedTime?.minutes, second: savedTime?.seconds) model.changeThreshold(threshold: new_threshold) } } .onChange(of: model.thresholdToDiscourage) { BeeFreeSchedule.setSchedule() // ... I believe I am using the latest stable version of Xcode (recently deleted and reinstalled). I'm really new to mobile development to Swift so any help is greatly appreciated. Thank you! :)
5
1
935
Feb ’24
How can DeviceActivityMonitor extension communicate with my main app?
At 11:37 in this video - https://developer.apple.com/videos/play/wwdc2021/10123/ - Nolan instantiates MyModel() in swiftui view file. And then at 12:02 he just uses MyModel from extension. I have the exact same code and when I try to build my project, it fails with error that MyModel() could not be found. I shared my MyModel.swift file between extension target and main app. Now it builds. However, it seems there are two separate instances of MyModel. What is proper way for DeviceActivityMonitor extension to pass data to main app? I simply want to increment counter from extension every minute and let the main app to know that. Or even better, - is there a way to use SwiftData from Device Activity Monitor extension?
1
0
615
Feb ’24
Shield Configuration Extension sometimes doesn't update on app switcher
Sometimes the app switcher doesn't show the correct shield configuration if there is like 7 or more apps in the app switcher. if I clear all apps from app switcher cache and leave 4 apps, the correct shield configuration will show every time instantly when I change the shield configuration from my parent app and go back to the app switcher; but if there is like 7 or more apps in the app switcher, I can see some of the app's shield configurations don't update instantly and I have to scroll past the app in the app switcher and go back to for it to update to the correct shield if it does at all. This is misleading to users and in the case of my app detrimental to one of its core functionalities override func configuration(shielding application: Application) -> ShieldConfiguration { let sharedUserDefaults = UserDefaults(suiteName: SharedUserDefaults.suiteName.rawValue)! let isPaidOn = sharedUserDefaults.bool(forKey: SharedUserDefaults.paidSwitchKey.rawValue) if isPaidOn == true { return ShieldConfig.paid } else { return ShieldConfig.free } }
0
0
547
Feb ’24
[iOS 17.4] Default value for DeviceActivityEvent's includesPastActivity should be set to true
Starting with iOS 17.4, the DeviceActivityEvent initializer includes a new parameter named includesPastActivity.

The default value for this parameter is set to false, whereas device activity events have behaved as though this parameter were set to true up until now. This breaking change is a MAJOR ISSUE for developers who used device activity events in their apps before iOS 17.4 because their apps might not work the way they intended after the update. They'll have to release new app versions that specifically set includesPastActivityto true. In my opinion, the default value for includesPastActivity should be true to avoid disrupting events scheduled on older versions of iOS. I have filed an enhancement report (FB13573556) about this. I really hope this is changed before the official iOS 17.4 release.
4
4
1.4k
Mar ’24
How to watch changes on fields of `@Published FamilyActivitySelection`?
class MyModel: ObservableObject { @Published var selection = FamilyActivitySelection() init() { $selection.sink { newSelection in print(newSelection) } } } class MyView: View { @StateObject var model = MyModel() // some body // .... // my method func removeToken(token: ApplicationToken) { model.selection.applicationTokens.remove(token) } } I am using the above code. When I call removeToken, the callback from the sink (which is registered in init() of MyModel) is called without any changes. newSelection still contains the token that I removed. Currently, I am using the additional code below to work around the problem. .onChange(of: model.selection.applicationTokens) { newSet in model.selection.applicationTokens = newSet } Should I use the workaround solution, or am I missing something?
1
0
667
Jan ’24
Uploading app with Family Controls to TestFlight
Our app uses Family Control and have 2 extensions for monitoring and shielding. We got Family controls Distribution entitlement for main app bundle and we have applied to get for extensions too, but its like 2 months we didn't get the Distribution entitlements for extensions. We need to upload the app to TestFlight, but without Distribution entitlements for extensions we can't do it. Bundle id exp: com.example.example -- Distribution entitlement provided com.example.example.MonitorExtension -- only development entitlement com.example.example.ShieldConfiguratoionExtension -- only development entitlement Is there nay workaround?
3
1
842
Feb ’24
App with DeviceActivityReport extension either won't install on device or won't upload to TestFlight
We have integrated DeviceActivityReport to our Family Controll app. All capabilities are added. We built the app and tested it, but when we want to upload to TestFlight the following error happened (see attached image) When we are adding NSExtensionMainStoryboard or NSExtensionPrincipalClass the following error appears during installation process. DeviceReport.appex with id com.example.example.DeviceReport defines either an NSExtensionMainStoryboard or NSExtensionPrincipalClass key, which is not allowed for the extension point com.apple.deviceactivityui.report-extension
1
0
577
Jan ’24
Screen Time Issue - Can't allow 3rd party aps
Experiencing a very strange issue with 3rd party permissions not working on screen time as of yesterday on my device (iPhone 12, iOS 17.2.1) and we are concerned that other users may end up dealing with this if it's not resolved. The video attached demonstrates what I mean but this is happening across every single screen time application, not just Opal or ours. I tried resetting my device, hard reboots, deleting and redownloading the apps, updating my phone, and turning screen time off and back on but nothing has worked. I also submitted my feedback (FB13540567)
1
1
472
Jan ’24
ManagedSettingsStore.clearAllSettings() sometimes doesn't work
Hi there, just bumping on whether this problem is being looked at. My feedback says there are "no similar reports," but it has been happening since the inception of Screen Time API. This feedback has two separate sysdiagnoses: FB11888225 To clarify the problem: sometimes when calling ManagedSettingsStore.clearAllSettings(), MY apps shield is cleared but it still shows the Apple's default shield. So the end result is the app remains blocked. I would guess that Apple has code that synchronizes all the settings and as it tried to process my apps settings, it "cleared my apps settings," but failed to clear the "global" settings due to interprocess communication issues. If I am any correct, I'm sure it's tricky to solve, but maybe there can be some patches/hacks to add SOME extra reliability: ex. add timer/cron to double-check the integrity of ManagedSettingsStore. This is a daily problem for my users, and it's a scary one. Sometimes users delete the app, and the block screens remain. One of the only solutions is to restart their device. Imagine scenarios where users have an emergency, but they aren't able to resolve it. Here is one App Store 1-star review just to give a picture: "This app wrecked my phone. When 'pausing' a focus session, apps are not available. After a focus session ends, apps are not available. After deleting the app, apps are not available. Thank goodness I removed the Phone app from filtering in case I needed to call 911. This app is extremely dangerous. I am still dealing with website content being blocked. Of all things I can’t access the CaringBridge website to receive updates on my sick friend. I had to get in touch with apple support to fix the damage this app has done to my phone. I have never regretted installing an app more." As always, I'm always happy to send more data/answer questions.
0
1
499
Jan ’24
4+ weeks of waiting for Family Controls Entitlement
Over a month ago, I submitted the Family Controls Entitlement form: https://developer.apple.com/contact/request/family-controls-distribution For an app I'm developing and I've received 0 feedback. No case number, no email and I've called and emailed support 3 times but they haven't been able to help me. When can I expect to hear back from the Family Controls team, what's the average wait time.
6
3
967
Feb ’24
FamilyActivityPicker Crashing / Freezing
Our users report frequent crashes with the FamilyActivityPicker. Since this is a screen controlled by Apple, I'm assuming that there's nothing I can do to prevent these crashes. I'm wondering, though, if there's any way to gracefully handle these crashes? When this happens, the following is printed to the console: [com.apple.FamilyControls.ActivityPickerExtension(1121)] Connection to plugin invalidated while in use. Does anyone know how to handle/catch this error?
2
2
888
Jan ’24
Providing Pre-Selections to FamilyActivityPicker?
I am able to correctly select and store the tokens of apps and categories my users will block, but I am unable to pre-populate Picker whenever the app is rebooted with previously selected and stored tokens. Below is the selection variable I am passing to the picker... var selectionsToBlock = FamilyActivitySelection() { willSet { saveSelection(selection: newValue) blockersSelected = true } } Is there any way I can provide my existing blockers (shown below) so that the user can easily edit their list of restricted apps from the Picker? func savedBlockers() -> FamilyActivitySelection? { let defaults = UserDefaults.standard guard let data = defaults.data(forKey: userDefaultsKey) else { return nil } return try? decoder.decode( FamilyActivitySelection.self, from: data ) }
2
0
667
Feb ’24
Limiting / Blocking App Access to FamilyActivitySelection for 30 minute interval
Hello, I am able to have users properly select apps that my app can limit and block, however I am having a lot of trouble figuring out how to restrict access for set periods of times. For example, I want the user to select the apps they wish to block, store them so they can be reused later and whenever they press a button restrict access for the next 30 minutes. I understand this is doable if they are actively on the app, but I do not know how to automate the lifting of this restriction after the given period. Moreover, what is the best way to persist the category and application tokens selected via the FamilyActivitySelector?
0
0
457
Dec ’23
Can I disable Family Sharing?
A good number of my users are having trouble when trying to use Family Sharing for my app. The feature is enabled in AppStoreConnect, but apparently I'm not allowed to disable it once it has been enabled. Is there any workaround to disable it again? On some users device the app simply won't start after they try to enter with Family Sharing. And even if they disable family sharing on their device, the same problem occurs. So basically, once they tried to connect to our Premium product through a family members subscription, they seem forever unable to use the app again. Any thoughts? Thanks
2
0
542
Dec ’23
ScreenTime API: Should the app used by the parent and the child be the same for FamilyActivityPicker to work?
Note: All the devices/accounts mentioned below are part of the same Family Group/ Is it necessary for the "parent-side" application (that uses FamilyActivityPicker to select the list of restricted apps) to be the same as the "child-side" application (that will request FamilyControls permission and will implement the DeviceActivityMonitor extension), for FamilyActivityPicker to work as expected? My observation is that given the FamilyControls permission being granted on the child device, FamilyActivityPicker when used on the parent device and rendered on an app with a different bundle identifier works as expected (by populating all the apps installed on the child device) in case of iOS 16 and 17, but does not work for iOS 15 (I am testing on iOS 15.8).
0
0
363
Dec ’23