Post

Replies

Boosts

Views

Activity

Reply to How do I persist the Family Activity Picker?
Sorry I am not sure why my contentView didn't post. Here is all of my code that I used from contentView to try and save the selection in the list using the files I already posted - import SwiftUI import DeviceActivity import FamilyControls import ManagedSettings struct ScaleButtonStyle: ButtonStyle { func makeBody(configuration: Configuration) -> some View { configuration.label .scaleEffect(configuration.isPressed ? 0.95 : 1.0) .opacity(configuration.isPressed ? 0.8 : 1.0) } } struct ContentView: View { @Environment(\.managedObjectContext) var moc // @FetchRequest(sortDescriptors: []) var apps: FetchedResults<AppToken> @State private var isSelected = false @State var isPresented = false @EnvironmentObject var model: DataModel @EnvironmentObject var dataController: DataController @State private var authorizationStatus = AuthorizationCenter.shared.authorizationStatus var body: some View { ZStack{ Color(red: 33 / 255, green: 33 / 255, blue: 33 / 255) .ignoresSafeArea() VStack{ Spacer() if dataController.savedSelection.isEmpty { Text("No Apps Selected") .foregroundColor(.gray) } else { List(dataController.savedSelection, id: \.self) { app in Text(app.bundleIdentifier ?? "Unknown App") } .scrollContentBackground(.hidden) } let appArray = dataController.savedSelection if !appArray.isEmpty{ Button("Delete App") { let app = dataController.savedSelection[0] moc.delete(app) do { try moc.save() // Update savedSelection to reflect the changes dataController.fetchApps(context: moc) } catch { print("Error saving after deletion: \(error)") } } .padding(.top, 15) } Spacer() VStack{ Button(action: { print("Blocking Button Clicked") isPresented = true }) { Text("Select Apps to Block") .font(.headline) .foregroundColor(.white) .padding() .frame(width: 300) .background( LinearGradient( colors: [.blue, .purple], startPoint: .leading, endPoint: .trailing ) ) .cornerRadius(20) .shadow(color: Color.blue.opacity(0.6), radius: 10, x: 0, y: 2) } .familyActivityPicker(isPresented: $isPresented, selection: $model.selectionToDiscourage) .buttonStyle(ScaleButtonStyle()) } .onChange(of: model.selectionToDiscourage) { print("APPS SELECTED : \(model.selectionToDiscourage.applications.count)") for i in model.selectionToDiscourage.applications { print(i) dataController.addApp(name:i.localizedDisplayName ?? "Temp", context: moc) } model.setShieldRestrictions() print($model.selectionToDiscourage.applicationTokens) } .padding(.bottom, 15) .padding(.top, 15) } .onAppear() { print("Screen Time Authorization Status \(authorizationStatus)") ScheduleModel.setSchedule() dataController.fetchApps(context: moc) } } } }
5d
Reply to How do I persist the Family Activity Picker?
Yes those steps are exactly what I am trying to achieve! I had to remove some things so you can only see what I was trying to work on but let me know if you need anything else. I also put my contentView in a second reply because I went over the word count. Thank you so much!!! Here is all of the code I used to try and persist the data so far - // DataController.Swift (the entity is AppToken and Attribute is bundleIdentifier set to a string in my Detoxifier.xcdatamodeld file) - import CoreData import Foundation import FamilyControls import ManagedSettings private let _DataController = DataController() class DataController: ObservableObject { let container = NSPersistentContainer(name: "Detoxifier") @Published var savedSelection: [AppToken] = [] init(){ container.loadPersistentStores { description, error in if let error = error{ print("ERROR LOADING CORE DATA. \(error)") }else{ print("Successfully loaded core data.") } } // fetchApps() } func fetchApps(context: NSManagedObjectContext){ let request = NSFetchRequest<AppToken>(entityName:"AppToken") do{ savedSelection = try context.fetch(request) print("Successfully fetched saved apps.") }catch let error{ print("Error fetching. \(error)") } } func addApp(name: String, context: NSManagedObjectContext){ let newApp = AppToken(context: context) newApp.bundleIdentifier = name saveData(context: context) } func saveData(context: NSManagedObjectContext) { do{ try context.save() fetchApps(context: context) } catch let error{ print("Error saving. \(error)") } } class var shared: DataController { return _DataController } } // MyModel.Swift - import Foundation import FamilyControls import ManagedSettings private let _DataModel = DataModel() class DataModel: ObservableObject { let store = ManagedSettingsStore() @Published var selectionToDiscourage: FamilyActivitySelection init() { selectionToDiscourage = FamilyActivitySelection() } class var shared: DataModel { return _DataModel } func setShieldRestrictions() { let applications = DataModel.shared.selectionToDiscourage store.shield.applications = applications.applicationTokens.isEmpty ? nil : applications.applicationTokens store.shield.applicationCategories = applications.categoryTokens.isEmpty ? nil : ShieldSettings.ActivityCategoryPolicy.specific(applications.categoryTokens) } } // App.Swift - import SwiftUI import FamilyControls import ManagedSettings @main struct AppBlockerApp: App { let center = AuthorizationCenter.shared @StateObject var model = DataModel.shared @StateObject var dataController = DataController.shared @StateObject var store = ManagedSettingsStore() @State var show = false var body: some Scene { WindowGroup { ZStack { VStack { if show { ContentView() .environmentObject(model) .environmentObject(store) .environmentObject(dataController) .environment(\.managedObjectContext, dataController.container.viewContext) }else{ LoadingView() } } }.onAppear { Task{ do{ print("Making Sure Authorization is Granted...") try await center.requestAuthorization(for: FamilyControlsMember.individual). show = true }catch{ print("Authorization request failed: \(error)") } } } } } } // Change background and animation so it matches app style struct LoadingView: View { var body: some View { ZStack{ Color(red: 33 / 255, green: 33 / 255, blue: 33 / 255) .ignoresSafeArea() ProgressView { Text("Loading") .font(.largeTitle) // Large and prominent font size .fontWeight(.bold) // Makes the text bold .foregroundColor(.white) // Matches the app theme .padding() } } } }
5d
Reply to DeviceActivityReport not showing report data to main app
I am getting the exact same error! Not sure how I am failing to grant permission in my main app as well. I even checked with print statements in my code to see if the Screen Time Authorization status was approved like this - print("Screen Time Authorization Status (authorizationStatus)") This was the full error when I attempted to run DeviceActivityReport(appsConext, filter: filter) -- LaunchServices: store (null) or url (null) was nil: Error Domain=NSOSStatusErrorDomain Code=-54 "process may not map database" UserInfo={NSDebugDescription=process may not map database, _LSLine=68, _LSFunction=_LSServer_GetServerStoreForConnectionWithCompletionHandler} Attempt to map database failed: permission was denied. This attempt will not be retried. Failed to initialize client context with error Error Domain=NSOSStatusErrorDomain Code=-54 "process may not map database" UserInfo={NSDebugDescription=process may not map database, _LSLine=68, _LSFunction=_LSServer_GetServerStoreForConnectionWithCompletionHandler}
2w