Scheduling would not begin and finish robotically utilizing the screentime API. The one approach I’ve obtained it to work is asking MyModel.shared.setAppRestrictions() manually after which by calling MyModel.shared.stopAppRestrictions() manually to cease it.
I’ve tried calling setAppRestrictions from the DeviceActivityCenter too however that did not work. Once I name setScedule() from AppDelegate then it blocks the app ceaselessly and by no means unblocks them on time. I’m very misplaced.
Listed here are my recordsdata for each MyModel and MySchedule
import FamilyControls
import Basis
import ManagedSettings
class MyModel: ObservableObject {
static let shared = MyModel()
let retailer = ManagedSettingsStore()
@Revealed var selectionToDiscourage: FamilyActivitySelection
personal let decoder = PropertyListDecoder()
init() {
selectionToDiscourage = FamilyActivitySelection()
selectionToDiscourage = loadSelection() ?? FamilyActivitySelection()
}
func setShieldRestrictions() {
// Pull the choice out of the app's mannequin and configure the applying protect restriction accordingly
let functions = MyModel.shared.selectionToDiscourage
retailer.protect.functions = functions.applicationTokens.isEmpty ? nil : functions.applicationTokens
retailer.protect.applicationCategories = functions.categoryTokens.isEmpty
? nil
: ShieldSettings.ActivityCategoryPolicy.particular(functions.categoryTokens)
//retailer.software.denyAppRemoval = true
//retailer.dateAndTime.requireAutomaticDateAndTime = true
}
func stopAppRestrictions() {
// lock software
retailer.protect.functions = nil
retailer.protect.applicationCategories = nil
// extra guidelines
retailer.media.denyExplicitContent = false
// forestall app elimination
retailer.software.denyAppRemoval = false
print("deny app elimination: ", retailer.software.denyAppRemoval ?? false)
// forestall set date time
retailer.dateAndTime.requireAutomaticDateAndTime = false
}
func loadSelection() -> FamilyActivitySelection? {
guard let information = UserDefaults.customary.information(forKey: "appModel") else {
return nil
}
return attempt? decoder.decode(FamilyActivitySelection.self, from: information)
}
}
import DeviceActivity
import Basis
import SwiftUI
extension DeviceActivityName {
static let day by day = Self("day by day")
}
class MonitoringStatus: ObservableObject {
@Revealed var isMonitoring: Bool = false
}
// The Gadget Exercise schedule represents the time bounds wherein my extension will monitor for exercise
enum MySchedule {
public static func unsetScedule() {
let middle = DeviceActivityCenter()
if middle.actions.isEmpty {
return
}
middle.stopMonitoring()
}
public static func setSchedule() {
@AppStorage("fromTime") var fromTime = ""
@AppStorage("toTime") var toTime = ""
let selectedDays = getSelectedDays()
for day in selectedDays {
let weekdayNumber = dayToWeekdayNumber(day)
createSchedule(weekdayNumber: weekdayNumber, fromTime: fromTime, toTime: toTime)
}
}
personal static func getSelectedDays() -> [Day] {
guard let dayStrings = UserDefaults.customary.object(forKey: "selectedDays") as? [String] else {
return []
}
return dayStrings.compactMap { Day(rawValue: $0) }
}
personal static func createSchedule(weekdayNumber: Int, fromTime: String, toTime: String) {
let startTimeComponents = convertStringToDateComponents(fromTime, weekday: weekdayNumber)
let endTimeComponents = convertStringToDateComponents(toTime, weekday: weekdayNumber)
let schedule = DeviceActivitySchedule(
intervalStart: startTimeComponents,
intervalEnd: endTimeComponents,
repeats: true // This could most likely be true for a weekly repeating schedule
)
let middle = DeviceActivityCenter()
do {
let activityName = DeviceActivityName("daily_(weekdayNumber)")
print("Mointor (weekdayNumber) with exercise identify (activityName)...")
attempt middle.startMonitoring(activityName, throughout: schedule)
} catch {
print("Error monitoring schedule: ", error)
}
}
}
personal func convertStringToDateComponents(_ timeString: String, weekday: Int) -> DateComponents {
var parts = convertStringToDateComponents(timeString)
parts.weekday = weekday
return parts
}
personal func convertStringToDateComponents(_ timeString: String) -> DateComponents {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "HH:mm"
if let date = dateFormatter.date(from: timeString) {
let calendar = Calendar.present
let hour = calendar.element(.hour, from: date)
let minute = calendar.element(.minute, from: date)
return DateComponents(hour: hour, minute: minute)
} else {
// Deal with invalid string format or return a default worth
return DateComponents()
}
}
personal func dayToWeekdayNumber(_ day: Day) -> Int {
// Regulate primarily based in your calendar's first weekday (e.g., Sunday = 1, Monday = 2, and many others.)
change day {
case .Sunday: return 1
case .Monday: return 2
case .Tuesday: return 3
case .Wednesday: return 4
case .Thursday: return 5
case .Friday: return 6
case .Saturday: return 7
}
}