Managed Settings

RSS for tag

Set restrictions for certain settings, such as locking accounts in place, preventing password modification, filtering web traffic, and shielding apps.

Posts under Managed Settings tag

109 Posts
Sort by:
Post not yet marked as solved
1 Replies
242 Views
I'm using the Screen Time API to shield apps the user selects. The problem is, that the apps are always shielded, even outside of the schedule. Here is my function initiateMonitoring: func initiateMonitoring(scheduleStart: DateComponents, scheduleEnd: DateComponents) { let schedule = DeviceActivitySchedule( intervalStart: scheduleStart, intervalEnd: scheduleEnd, repeats: true ) let center = DeviceActivityCenter() do { try center.startMonitoring(.daily, during: schedule) logger.log("STARTED MONITORING") } catch { logger.log("FAILED MONITORING: \(error.localizedDescription)") } } The expected result should be that the selected Apps should be blocked during the schedule the user specified, but not outside the schedule, but it is blocked 24/7. I've experimented with the DateComponents, but the issue may be somewhere else. What's maybe interesting is, I tried Logging the DeviceActivityMonitor and somehow it doesn't get called. The logging-output from initiateMonitoring is printed in the console, but for the DeviceActivityMonitor it's not. I implemented it as recommended as a separate Extension Target. For more context, here is my DeviceActivityMonitor: class DeviceActivityMonitorExtension: DeviceActivityMonitor { let store = ManagedSettingsStore() let logger = Logger() override func intervalDidStart(for activity: DeviceActivityName) { super.intervalDidStart(for: activity) logger.log("INTERVAL STARTED") let model = ShieldManager.shared let applications = model.selectionToDiscourage.applicationTokens let categories = model.selectionToDiscourage.categoryTokens let webCategories = model.selectionToDiscourage.webDomainTokens store.shield.applications = applications.isEmpty ? nil : applications store.shield.applicationCategories = ShieldSettings.ActivityCategoryPolicy.specific(categories, except: Set()) store.shield.webDomains = webCategories.isEmpty ? nil : webCategories } ... What's confusing me is that the apps are in fact shielded, so the MonitorExtension should be called, but neither the logging works nor my separate ShieldConfigurationExtension, maybe the issues are connected... Any help would be gladly appreciated!
Posted
by
Post not yet marked as solved
0 Replies
257 Views
There is a way to allow DeviceActivityMonitor to make UI changes? Currently I have some code in the intervalDidStart and intervalDidEnd that updates Core Data entities, and it works correctly. However, the changes are only reflected if the app is terminated and opened again. Thus, if the app is opened and one of the methods inside the DeviceActivityMonitor is being called, the UI won't be updated. PS: I am using @FetchRequest to retrieve the core data entities called BlockEntity, and I have a little circle in the UI which should indicate the status of the block: active/inactive, so it would be nice to update the color in real time when intervalDidStart or intervalDidEnd are called.
Posted
by
Post marked as solved
1 Replies
275 Views
I want to block specific Websites with FamilyControls in my App. To do this, I need to access the WebDomainTokens of a specific Website, without the user selecting it in the FamilyActivityPicker. I basically just want to have a button e.g. "Block Instagram" and when clicking it, the instagram website is blocked. I don't see any way in accessing the WebDomainToken without the FamilyActivityPicker. Or is there maybe another approach to this problem? Currently I tried the following: var selectionToDiscourage = FamilyActivitySelection() { willSet { let applications = newValue.applicationTokens store.shield.applications = applications.isEmpty ? nil : applications let webDomain: WebDomain = .init(domain: "https://www.instagram.com/") print("TOKEN: \(webDomain.token)") print("DOMAIN: \(webDomain.domain)") if let webDomainToken = webDomain.token { let webDomainTokenSet: Set<WebDomainToken> = [webDomainToken] store.shield.webDomains = webDomainTokenSet } } } But when only giving the domain, the token always prints nil. Hope someone can help!
Posted
by
Post not yet marked as solved
0 Replies
325 Views
We are not seeing the restriction profile configuration to restrict allowMarketplaceAppInstallation" for 17.4 where the the system prevents installation of alternative marketplace apps from the web and prevents any installed alternative marketplace apps from installing apps. Needed for iOS 17.4 DEVICES. how to achieve this any suggestions ?.
Posted
by
Post marked as solved
1 Replies
380 Views
I am trying to understand how to approach 'x minute' pauses for a DeviceActivitySchedule. For instance, I would like to let the user pause for 5 minutes from an active schedule (meaning un-shielding the apps and re-applying the shield after the 5 min has passed). The only way that came to my mind was calling the following: Calling .startMonitoring to start monitoring a new event with the same apps starting .now and ending .now + 5 minutes; Calling in the intervalDidStart, store.shield.applications.subtract(apps) so that the apps are removed from the shield. Calling in the intervalDidEnd, store.shield.applications = apps so that the apps are now shielded again. The problem is that, from the Apple Developer Documentation: The minimum interval length for monitoring device activity is fifteen minutes. So the minimum pause I could offer to the user would be 15 minutes. And that tells me this approach is most likely wrong, because all other Screen Time apps, like Opal, Jomo, AppBlock offer also 5 min pause. Does anyone know / can think of a different and better approach?
Posted
by
Post not yet marked as solved
1 Replies
265 Views
An app that uses screen time API. After asking for permission and receiving them works, everything generally work, shields applications etc.. Upon new version update (manually update from testFlight old version or App Store) I get an error message, I can then update again without any error but the permissions are revoked and I have to ask for them again. shielding stopes. This happens randomly on TestFlight or App Store and the permissions Did anyone encounter this or solved this? this seems to have started a month ago but maybe I just missed it before
Posted
by
Post not yet marked as solved
0 Replies
180 Views
I need to achieve the following behaviour in my App When the app is run for the first time, prompt the user to authenticate by entering their administrative password. Upon successful authentication, securely store the administrative password using macOS Keychain Access. For subsequent executions of the same command, retrieve the stored password from the Keychain and use it to execute the privileged command without requiring the user to enter the administrative password again. By implementing this approach, users will only need to authenticate once, and subsequent executions of the privileged command will be seamless without further authentication prompts. Let me know is it required any specific entitlement? How can we achieve this?
Posted
by
Post marked as solved
3 Replies
335 Views
Dear all, I'm quite new to Xcode. I'm trying to set up my first project - I'd like to create a macOS and iPad app. So I'm following the steps in Xcode, but receiving errors. I'm attaching the steps I'm following with the details of what Xcode is giving me as error. C o Could you please give me indications on how to solve the issue? Thanks, Andrea
Posted
by
Post not yet marked as solved
0 Replies
231 Views
I have implemented a shielding mechanism via Family Controls to prevent unauthenticated users from deleting specific shortcuts within the Shortcuts app. While this successfully secures the app, it has an unintended consequence: the Shortcuts app no longer appears in Spotlight Search and becomes inaccessible for users subject to this shielding. I understand that this is the default behavior when implementing app shielding or time limits on specific apps. Is there a way to retain the app's visibility in Spotlight Search despite it being shielded?
Posted
by
Post not yet marked as solved
2 Replies
468 Views
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! :)
Posted
by
Post not yet marked as solved
0 Replies
301 Views
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 } }
Posted
by
Post not yet marked as solved
1 Replies
727 Views
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.
Posted
by
Post not yet marked as solved
1 Replies
429 Views
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 ) }
Posted
by
Post not yet marked as solved
1 Replies
711 Views
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?
Posted
by
Post not yet marked as solved
0 Replies
427 Views
I have posted this already in Feedback Assistant back in September with detailed steps to reproduce and have not heard back. Posting a brief overview here in hopes that Apple acknowledges and addresses this issue that is still present in recent Sonoma betas. This is preventing our organization from updating to Sonoma, however the Apple maximum update deferral timeline of 90 days is running out at Christmas. The Switch User option is missing from the Lock Screen on macOS Sonoma if only one person has ever signed in for an enterprise device with an MDM pushed (and verified) configuration profile which allows user switching and network users to sign in to the device. It only shows users who are not hidden and have a home folder. This locks out all users without a hard reboot if nobody else exists on the device, or the user can do something that is very unintuitive if there are 2 or more users who have signed in. They can click any other user than the one who was logged in when the lockscreen process started, and that will let them erase the username of the user they clicked and log in themselves. What is missing is "Other..." or "Switch User", which were on the Lock Screen for pervious versions of macOS. The login screen works just fine, it's the lock screen that's now ignoring configuration profiles or just doesn't have the same settings as the loginwindow process.
Posted
by
Post not yet marked as solved
1 Replies
609 Views
We have an app that uses the Screen Time APIs to block certain apps set by the user on a schedule: We use ManagedSettings to shield selected apps We use DeviceActivityMonitor to shield the apps automatically on a schedule set by the user. The shielding starts during the intervalDidStart callback function and ends during the intervalDidEnd callback function We are getting reports from the majority of our iOS 17 users that the app blocking schedules no longer work on iOS 17. We have tested this on our own iOS 17 devices and reproduced the behavior. But the feature still works consistently on iOS 16 devices. The app is still built using Xcode 14 instead of Xcode 15 due to another issue - the DeviceActivityReport is blank for all iOS 16 users when built in Xcode 15 (link to issue on the developer forums: https://developer.apple.com/forums/thread/735915). When testing with Xcode 15 builds, the bug appears to improve - however it still occurs intermittently. Are there any other mechanisms to run tasks on repeating schedules? For this specific feature, we don't need to eventDidReachThreshold callbacks, which is the main purpose of DeviceActivityMonitor. So we really don't need any Device Activity integration at all, just setting and disabling ManagedSettings shields at certain times. Would love if anyone could suggest and alternative to DeviceActivityMonitor.
Posted
by
Post not yet marked as solved
0 Replies
402 Views
Any way that I try requesting authorization for family controls is incredibly inconsistent. The line of code that hangs is **let center = AuthorizationCenter.shared ** I've looked at other posts and I saw someone recommended declaring let center = AuthorizationCenter.shared outside the main thread and somehow get the status on the main thread. I've tried that approach with no success. I've scoured GitHub to see how other people approach the request but it's all pretty similar. The following code sometimes works great for a few minutes and then I rebuild and run and it hangs on AuthorizationCenter.shared.requestAuthorization(for: FamilyControlsMember.individual). Would love any suggestions!!! .onAppear { Task { do { print("try requestAuthorization") try await AuthorizationCenter.shared.requestAuthorization(for: FamilyControlsMember.individual) print("requestAuthorization success") switch AuthorizationCenter.shared.authorizationStatus { case .notDetermined: print("not determined") case .denied: print("denied") case .approved: print("approved") @unknown default: break } } catch { print("Error requestAuthorization: ", error) } } }
Posted
by
Post not yet marked as solved
0 Replies
280 Views
I have gained the PassKit access, but don't know how to configure com. Apple. Developer. PassKit. Pass the presentation - suppression the permissions. Who can tell us the detailed process, which Capabilities should be configured in the App ID?
Posted
by