With the recent changes to allow for an app to be completely in SwiftUI, I am trying to re-create a simple core data and SwiftUI app.
How can a NSPresistantContainer be setup with the new app delegate adaptor and scene builder? I have attempted what has worked previously by creating a lazy var in the app delegate and then providing that as an adaptor on the app struct.
What is the correct way to setup the NSPresistantContainer so the NSManagedObjectModel is loaded?
How can a NSPresistantContainer be setup with the new app delegate adaptor and scene builder? I have attempted what has worked previously by creating a lazy var in the app delegate and then providing that as an adaptor on the app struct.
What is the correct way to setup the NSPresistantContainer so the NSManagedObjectModel is loaded?
Code Block swift class AppDelegate: NSObject, UIApplicationDelegate { func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { if isDataSet() == false { setDefaultData() } return true } lazy var persistentContainer: NSPersistentContainer = { let container = NSPersistentContainer(name: "breakapp") container.loadPersistentStores(completionHandler: { (storeDescription, error) in if let error = error as NSError? { fatalError("Unresolved error \(error), \(error.userInfo)") } }) return container }() func saveContext () { let context = persistentContainer.viewContext if context.hasChanges { do { try context.save() } catch { let nserror = error as NSError fatalError("Unresolved error \(nserror), \(nserror.userInfo)") } } } func setDefaultData() { guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else { return } let managedContext = appDelegate.persistentContainer.viewContext for (i, weekday) in Constants.CoreData.weekdays.enumerated() { let user = NSManagedObject(entity: Weekday.entity(), insertInto: managedContext) user.setValue("\(weekday)", forKey: Constants.CoreData.Attributes.label) user.setValue(i, forKey: Constants.CoreData.Attributes.sortNumber) } try? managedContext.save() } func isDataSet() -> Bool { guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else { return true } let managedContext = appDelegate.persistentContainer.viewContext let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: Constants.CoreData.Entities.weekday) let result = try? managedContext.fetch(fetchRequest) return result?.count != 0 } } @main struct TakeABreakApp: App { @UIApplicationDelegateAdaptor private var appDelegate: AppDelegate @Environment(\.scenePhase) private var scenePhase var body: some Scene { WindowGroup { ContentView() } } } struct TakeABreakApp_Previews: PreviewProvider { static var previews: some View { ContentView() } }
Solved it with this:
and
Code Block swift import CoreData public class MyPersistentContainer { public static var context: NSManagedObjectContext { return persistentContainer.viewContext } private init() { } public static var persistentContainer: NSPersistentContainer = { let container = NSPersistentContainer(name: "breakapp") container.loadPersistentStores(completionHandler: { (storeDescription, error) in if let error = error as NSError? { fatalError("Unresolved error \(error), \(error.userInfo)") } }) return container }() public static func saveContext () { let context = persistentContainer.viewContext if context.hasChanges { do { try context.save() } catch { let nserror = error as NSError fatalError("Unresolved error \(nserror), \(nserror.userInfo)") } } } }
and
Code Block swift import SwiftUI import CoreData @main struct TestApp: App { let context = MyPersistentContainer.persistentContainer.viewContext var body: some Scene { WindowGroup { ContentView().environment(\.managedObjectContext, context) } } }